题目
Description
Input
Output
Sample Input1
3 4 4
R 2 4
S 4 1
R 3 2
R 2 0
Sample Input2
2 4 4
S 2 0
S 2 3
R 1 5
S 1 3
Sample Output1
94
Sample Output2
80
Data Constraint
Hint
分析
记录每行每列被翻了多少倍为
R
i
R_i
Ri,
S
i
S_i
Si,显然答案为
A
n
s
=
∑
i
=
1
n
∑
j
=
1
m
R
i
S
j
(
i
(
m
−
1
)
+
j
)
=
∑
i
=
1
n
R
i
∑
j
=
1
m
(
S
j
⋅
i
(
m
−
1
)
+
S
j
⋅
j
)
=
∑
i
=
1
n
R
i
(
∑
j
=
1
m
S
j
⋅
i
(
m
−
1
)
+
∑
j
=
1
m
S
j
⋅
j
)
\begin{aligned} Ans&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}R_iS_j(i(m-1)+j)\\ &=\sum\limits_{i=1}^{n}R_i\sum\limits_{j=1}^{m}(S_j\cdot i(m-1)+S_j\cdot j)\\ &=\sum\limits_{i=1}^{n}R_i\left(\sum\limits_{j=1}^{m}S_j\cdot i(m-1)+\sum\limits_{j=1}^{m}S_j\cdot j\right) \end{aligned}
Ans=i=1∑nj=1∑mRiSj(i(m−1)+j)=i=1∑nRij=1∑m(Sj⋅i(m−1)+Sj⋅j)=i=1∑nRi(j=1∑mSj⋅i(m−1)+j=1∑mSj⋅j)
好了对
S
i
S_i
Si前缀和就好了。
这种题考试的时候做了2个多小时。NICE!
代码
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int read(){
int x=0;bool f=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=x*10+(c^48),c=getchar();
return f?-x:x;
}
#define LL long long
#define MAXN 10000000
#define INV 500000004
#define MOD 1000000007
int N,M,K,Ans;
int R[MAXN+5],S[MAXN+5];
int main(){
freopen("game.in" ,"r", stdin);
freopen("game.out","w",stdout);
N=read(),M=read(),K=read(),Ans=0;
for(int i=1;i<=N;i++) R[i]=1;
for(int i=1;i<=M;i++) S[i]=1;
while(K--){
char opt[10];
scanf("%s",opt);
int x=read(),p=read();
if(opt[0]=='R')
R[x]=(LL)R[x]*p%MOD;
else
S[x]=(LL)S[x]*p%MOD;
}
LL Sum1=0,Sum2=0;
for(int i=1;i<=M;i++)
Sum1=(Sum1+S[i])%MOD,
Sum2=(Sum2+(LL)S[i]*i%MOD)%MOD;
for(int i=1;i<=N;i++)
Ans=(Ans+(LL)R[i]*((Sum1*(i-1)%MOD*M%MOD+Sum2)%MOD)%MOD)%MOD;
printf("%d",Ans);
}