多校联合第九场1001HDU4686 Arc of Dream

来源:互联网 发布:js鼠标移入事件 编辑:程序博客网 时间:2024/04/30 10:03

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4686 

题意描述的很直观,给你公式:a0 = A0,ai = ai-1*AX+AY,b0 = B0,bi = bi-1*BX+BY,再给一个n要求从a0*b0到a(n-1)*b(n-1)的累加和。n很大,所以不用考虑暴力了。

从给的公式我们可以得到几点:

1).ai=AX *a(i-1)+AY;                                                                  

2).bi=BX*b(i-1)+BY;

3).  ai*bi=(AX*BX)*a(i-1)*b(i-1)+(AX*BY)*a(i-1)+(AY*BX)*b(i-1)+(AY*BY)*1;

设Si为累加到ai*bi的和,则

4).Si=S(i-1)+ai*bi;

所以可以构造出这样的矩形:

ai*bi           AX*BX   AX*BY   AY*BX  AY*BY  0                  a(i-1)*b(i-1)

ai                0           AX         0          AY      0                     a(i-1)

bi         =    0           0           BX       BY       0         *          b(i-1)

1                0           0            0        1            0                    1

si                AX*BX   AX*BY   AY*BX  AY*BY  1                   s(i-1)

最后再用矩阵的快速幂乘法就可以得到结果了,注意是(n-1)次,还有就是这题需要特判n==0的时候,不然会一直WA到底的。。。。=.=

贴一下代码:

#include <cstdio>#include <cstring>typedef long long LL;#define mod 1000000007LL matrix[5][5],tmp[5][5],mirror[5][5];LL A0,B0,AX,AY,BX,BY;void init()//初始化左乘矩阵{memset(matrix,0,sizeof(matrix));matrix[0][0]=AX*BX%mod,matrix[0][1]=AX*BY%mod,matrix[0][2]=AY*BX%mod,matrix[0][3]=AY*BY%mod,matrix[0][4]=0;matrix[1][1]=AX%mod,matrix[1][3]=AY%mod;matrix[2][2]=BX%mod,matrix[2][3]=BY%mod;matrix[3][3]=1;matrix[4][0]=AX*BX%mod,matrix[4][1]=AX*BY%mod,matrix[4][2]=AY*BX%mod,matrix[4][3]=AY*BY%mod,matrix[4][4]=1;memcpy(mirror,matrix,sizeof(matrix));}void matrix_mult(LL a[][5],LL b[][5] ){for(int i=0;i<5;i++)for(int j=0;j<5;j++){tmp[i][j]=0;for(int k=0;k<5;k++){tmp[i][j]+=(a[i][k]*b[k][j]%mod);tmp[i][j]%=mod;}}memcpy(a,tmp,sizeof(tmp));}void cal_matrix(LL n){memset(mirror,0,sizeof(mirror));for(int i=0;i<5;i++) mirror[i][i]=1;while(n){if(n&1)//二进制当前位为1matrix_mult(mirror,matrix);matrix_mult(matrix,matrix);n>>=1;} }void cal_ans(){LL ans=0;ans=(ans+mirror[4][0]*A0%mod*B0%mod)%mod;ans=(ans+mirror[4][1]*A0%mod)%mod;ans=(ans+mirror[4][2]*B0%mod)%mod;ans=(ans+mirror[4][3])%mod;ans=(ans+mirror[4][4]*A0%mod*B0%mod)%mod;printf("%I64d\n",ans );}int main(){LL n;while(scanf("%I64d",&n)==1)//注意在hdu上不能用lld{scanf("%I64d%I64d%I64d",&A0,&AX,&AY);scanf("%I64d%I64d%I64d",&B0,&BX,&BY);if(n==0){printf("0\n");continue;//不特判0会wa}init();cal_matrix(n-1);cal_ans();}return 0;}