2020 年 “联想杯”全国高校程序设计在线邀请赛H. Hay Mower
题意:n × m 网格图,每个格子内的草每秒增加 ai,j,接下
来 k 个操作,每个操作会在某个时间把某一列或某一行的草割光,
求最终割掉的草的总和 (题意直接抄官网的题解的,哈哈哈hhh)
题解:开这个a[n][m]数组存每个格子草生在的速率,再开一个数组b[n][m]存最后一次时间割草的时间,每个格子的贡献就算a[i][j]*b[i][j],两个for就完事,记得多模一下,但是时间这里别乱摸。
(因为同个格子内每秒增长的速率的相同,即使是有重复割同个格子,也是把多次的贡献做一个加法=从开始到最后一次割)(在全局开数组,默认初始化为0,如果没有出现过的格子保持为0,贡献当然还是0拉)
我这里用了一个快速乘法,其实没有必要,只是我当时怕卡时间。
直接看代码即可:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define _for(i,a,b) for(int i = (a);i<(b);i++)
#define endl '\n'
#define inf 0x3f3f3f3f
using namespace std;
const ll mod=998244353;
const int MAX=1e6+7;
ll a[505][505],b[505][505];
ll ans=0;
ll q_mul(ll a, ll b, ll mod) {
ll ans = 0;
while (b) {
if (b & 1) ans = (ans + a) % mod;
a = (a << 1) % mod;
b >>= 1;
}
return ans;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
ll n,m,k;cin>>n>>m>>k;
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
{
cin>>a[i][j];
a[i][j]%=mod;
}
char c;ll x,t;
for(ll i=1;i<=k;i++)
{
cin>>c>>x>>t;
if(c=='r'){
for(ll j=1;j<=m;j++)
b[x][j]=max(b[x][j],t);
}
if(c=='c'){
for(ll j=1;j<=n;j++)
b[j][x]=max(b[j][x],t);
}
}
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
{
ans+=(q_mul(a[i][j],b[i][j],mod))%mod;
ans%=mod;
}
cout<<(ans+mod)%mod;
}