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;
}