2020 年 “联想杯”全国高校程序设计在线邀请赛H. Hay Mower

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

你可能感兴趣的:(2020 年 “联想杯”全国高校程序设计在线邀请赛H. Hay Mower)