2016 pku campusH/OpenJ_POJ - C16H(推公式+矩阵快速幂)
传送门
题面:
Wenwen has a magical ball. When put on an infinite plane, it will keep duplicating itself forever.
Initially, Wenwen puts the ball on the location (x0, y0) of the plane. Then the ball starts to duplicate itself right away. For every unit of time, each existing ball on the plane will duplicate itself, and the new balls will be put on the adjacent locations. The duplication rule of these balls is, during the i-th unit of time, a ball, which locates at (x, y), will duplicate ui balls to (x, y+1), di balls to (x, y-1), li balls to (x-1, y) and ri balls to (x+1, y).
The duplication rule has a period of M. In another words, ui=ui-M, di=di-M, li=li-M, ri=ri-M, for i=M+1,M+2,...
Wenwen is very happy because she will get many balls. It is easy to calculate how many balls she will get after N units of time. However, she wants to know the sum of x-coordinates and y-coordinates of all balls after N units of time. This is a bit difficult for her. Could you help her? Since the sum might be very large, you should give the sum modulo 1,000,000,007 to her.
输入The first line contains an integer T (1 ≤ T ≤ 25), indicating the number of test cases.
For each test case:
The first line contains four integers N (1 ≤ N ≤ 10^18), M (1 ≤ M ≤ 20,000), x0 and y0 (-10^18 ≤ x0,y0 ≤ 10^18);
Then follows M lines, the i-th line contains four integers: ui, di, li and ri (0 ≤ ui,di,li,ri ≤ 10,000).输出For each test case, output one integer on a single line, indicating the sum of x-coordinates and y-coordinates of all balls after N units of time, modulo 1,000,000,007.样例输入
1
2 2 1 1
2 0 0 0
0 0 0 1
样例输出
19
Initially, there is 1 ball on (1,1).
After 1 unit of time, there is 1 ball on (1,1) and 2 balls on (1,2);
After 2 units of time, there is 1 ball on (1,1), 2 balls on (1,2), 1 ball on (2,1) and 2 balls on (2,2).
Therefore, after 2 units of time, the sum of x-coordinates and y-coordinates of all balls is
(1+1)*1+(1+2)*2+(2+1)*1+(2+2)*2=19.
题意:
题目分析:
1 #include <bits/stdc++.h> 2 #define maxn 100005 3 using namespace std; 4 const int mod=1e9+7; 5 typedef long long ll; 6 struct Matrix{ 7 ll mo[2][2]; 8 Matrix(){ 9 memset(mo,0,sizeof(mo)); 10 } 11 }; 12 Matrix Mul(Matrix x,Matrix y){ 13 Matrix c; 14 for(int i=0;i<2;i++){ 15 for(int j=0;j<2;j++){ 16 for(int k=0;k<2;k++){ 17 c.mo[i][j]=(c.mo[i][j]+x.mo[i][k]*y.mo[k][j])%mod; 18 } 19 } 20 } 21 return c; 22 } 23 Matrix powmod(Matrix x,ll n){ 24 Matrix res; 25 for(int i=0;i<2;i++){ 26 res.mo[i][i]=1; 27 } 28 while(n){ 29 if(n&1) res=Mul(res,x); 30 n>>=1; 31 x=Mul(x,x); 32 } 33 return res; 34 } 35 int A[maxn]; 36 int B[maxn]; 37 int main() 38 { 39 int t; 40 scanf("%d",&t); 41 while(t--){ 42 ll n,m,x0,y0; 43 scanf("%lld%lld%lld%lld",&n,&m,&x0,&y0); 44 x0=(x0%mod+mod)%mod; 45 y0=(y0%mod+mod)%mod; 46 for(int i=0;i<m;i++){ 47 int a,b,c,d; 48 scanf("%d%d%d%d",&a,&b,&c,&d); 49 A[i]=1+a+b+c+d; 50 B[i]=a-b+d-c; 51 } 52 Matrix base; 53 for(int i=0;i<2;i++){ 54 base.mo[i][i]=1; 55 } 56 for(int i=0;i<m;i++){ 57 Matrix tmp; 58 tmp.mo[0][0]=tmp.mo[1][1]=A[i],tmp.mo[1][0]=B[i]; 59 base=Mul(base,tmp); 60 } 61 base=powmod(base,n/m); 62 for(int i=0;i<n%m;i++){ 63 Matrix tmp; 64 tmp.mo[0][0]=tmp.mo[1][1]=A[i],tmp.mo[1][0]=B[i]; 65 base=Mul(base,tmp); 66 } 67 cout<<(base.mo[1][0]+base.mo[1][1]*(x0+y0))%mod<<endl; 68 } 69 return 0; 70 }