0916-A-矩阵游戏

矩阵游戏

LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个\(N\)\(M\)列的矩阵。
第一行的数字是 \(1,2,3,...,M\)
第二行的数字是 \(M+1,M+2,M+3,...,2*M\)
第三行的数字是 \(2 \times M+1,2 \times M+2,2 \times M+3,...,3 \times M\)
以此类推,第 N 行的数字是 \((N-1) \times M+1,(N-1) \times M+2,(N-1) \times M+3,...,N \times M\)
例如,\(N=3\),\(M=4\) 的矩阵是这样的:
1 2 3 4
5 6 7 8
9 10 11 12
对于身为智慧之神的LZK来说,这个矩阵过于无趣.于是他决定改造这个矩阵,改造会进行\(K\)次,每次改造会将矩阵的某一行或某一列乘上一个数字,
你的任务是计算最终这个矩阵内所有数字的和,输出答案对 \(10^9+7\)取模。

第一眼咦这道题感觉好难
不管了先敲个40分的暴力然后就真的只得了40分
首先肯定需要用一个\(r_i\)\(s_i\)数组把操作存下来(因为N,M的范围比较大,所以肯定是讨论K)
想到行列分开处理,不过想歪了orz,一下子想到先把行算了,再加上/减去算多/少了的部分,仔细思考一番过后发现做不出来,十分自闭

对于第j列,我们设一个\(Sum_j\)表示第j列的总和
有如下数学式子:(\(r_i\)\(s_i\)是预处理好的每一行需要乘的数和每一列需要乘的数)
\(sum_j=\sum_{i=1}^{n}\ r_i \times[m(i-1)+j]\)
展开可得
\(sum_j=\sum_{i=1}^{n}\ r_i \times m(i-1) + j \times \sum_{i=1}^{n}r_i\)
观察可知,\(\sum_{i=1}^{n}\ r_i \times m(i-1)\) 和 $ \sum_{i=1}^{n}r_i$两项与j的值无关
我们考虑
令K1 = \(\sum_{i=1}^{n}\ r_i \times m(i-1)\),
K2 = $ \sum_{i=1}^{n}r_i$
那么 \(sum_j=K1+K2 \times j\)
最后从左到右统计一遍答案
\(Ans = \sum_{j=1}^{m}\ sum_j \times s_j\)

最后,注意此题需要能%就%,不然会爆LL

#include<stdio.h>
#include<bits/stdc++.h>
#define maxn 1000005
#define LL long long
#define rel(i,s,n) for(int i=s;i<n;i++)
#define rep(i,s,n) for(int i=s;i<=n;i++)
#define red(i,s,n) for(int i=s;i>=n;i--)
#define res(i,x) for(int i=Last[x];i;i=Next[i]);
const int mod = 1e9+7;
using namespace std;
char C;
LL K1,K2,Ans;
LL N, M, X, Y, K;
LL S[maxn],R[maxn];
//S:列  R:行 
int main(){
	ios::sync_with_stdio(false);
	cin>>N>>M>>K;
	rep(i,1,N)R[i]=1;
	rep(j,1,M)S[j]=1;
	rep(i,1,K){
		cin>>C>>X>>Y;
		if(C=='S')S[X]*=Y;S[X]%=mod;
		if(C=='R')R[X]*=Y;R[X]%=mod;
	}
	rep(i,1,N){
		K1+=(((R[i]*M)%mod)*(i-1))%mod;
		K2+=R[i]%mod;
		K1%=mod;K2%=mod;
	}
	rep(j,1,M)Ans+=(((K1+(K2*j)%mod)%mod)*S[j])%mod,Ans%=mod;
	cout<<Ans;
	return 0;
}
posted @ 2019-09-17 19:07  羽错光阴  阅读(258)  评论(0编辑  收藏  举报