一夜回到解放前。
T1 矩阵游戏
三道题中最水的题,$A$了十几个,我$WA$ 0。
不得不说,实力至此。
将同行同列操作合并,归成一个操作,然后合并成一个串。
这需要感性的思考一下。假设我们现在让矩阵按列分成一个含$m$个元素的串,同一行中的每一位都乘上了一个相同元素,因为一行中原本元素与元素之间就是成等差数列的关系,乘上相同元素后肯定也还是等差数列的关系。每一行都是如此。
那么我们就得到了$n$个等差数列,让他们中的元素按列相加,得到的仍然是等差数列。这么算下来,时间不是$O(nm)$的么?其实,当我们暴力算出第一列的合并之后的元素,那么就可以递推地求出它之后的$m$个元素,原理还是等差数列,稍微想想就可以想懂了。
小弟不才。
1 #include<cstdio> 2 #define LL long long 3 #define int long long 4 using namespace std; 5 const LL MAXN=1e7+3; 6 const LL mod=1e9+7; 7 int n,m,Q; 8 LL ans,d,res,qp[2][MAXN]; 9 signed main() 10 { 11 scanf("%lld%lld%lld",&n,&m,&Q); 12 for (int i=1; i<=n; ++i) qp[0][i]=1; 13 for (int i=1; i<=m; ++i) qp[1][i]=1; 14 for (int i=1,x,y; i<=Q; ++i) 15 { 16 char opt=getchar(); 17 while (opt!='R' and opt!='S') opt=getchar(); 18 scanf("%lld%lld",&x,&y); 19 if (opt=='R') qp[0][x]=qp[0][x]%mod*y*1ll%mod; 20 else qp[1][x]=qp[1][x]%mod*y*1ll%mod; 21 } 22 for (int i=1; i<=n; ++i) 23 res=((res+((i-1)*m*1ll%mod+1)*1ll*qp[0][i]%mod)+mod)%mod,d=(d+qp[0][i])%mod; 24 ans=res%mod*qp[1][1]*1ll%mod; 25 for (int i=2; i<=m; ++i) 26 res=(res+d)%mod, ans=(ans+res%mod*1ll*qp[1][i])%mod; 27 printf("%lld ",ans); 28 return 0; 29 }