HDU 4686 - Arc of Dream
Posted nicetomeetu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4686 - Arc of Dream相关的知识,希望对你有一定的参考价值。
递推式:
a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY(AX,AY,BX,BY均为已知数字)
求 0-n-1 的 ai*bi 的和(设为 Sn 吧)
线性代数只能做线性变换,故要得出 ai*bi 的递推式
ai*bi = AXBX*ai-1*bi-1 + AXBY*ai-1 + BXAY*bi-1 + AYBY
然后写成矩阵
|1 AXBX AXBY BXAY AYBY| | Sn-1 | | Sn |
|0 AXBX AXBY BXAY AYBY| | an-1*bn-1| |an*bn|
|0 0 AX 0 AY | * | an-1 | = | an |
|0 0 0 BX BY | | bn-1 | | bn |
|0 0 0 0 1 | | 1 | | 1 |
最后用 快速幂 运算。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int mod=1000; 6 struct P{ 7 int a[20][20]; 8 }; 9 int n,m,t,a,b,k; 10 P s,c; 11 P mult(P a,P b) 12 { 13 P c; 14 memset(c.a,0,sizeof(c.a)); 15 for(int i=0;i<n;i++) 16 { 17 for(int j=0;j<n;j++) 18 { 19 for(int k=0;k<n;k++) 20 c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j] )%mod; 21 } 22 } 23 return c; 24 } 25 void fuc(int p,P s) 26 { 27 memset(c.a,0,sizeof(c.a)); 28 for(int i=0;i<n;i++) c.a[i][i]=1; 29 while(p) 30 { 31 if(p&1) 32 { 33 c=mult(c,s); 34 } 35 s=mult(s,s); 36 p>>=1; 37 } 38 } 39 int main() 40 { 41 while(~scanf("%d%d",&n,&m)&&(m+n)) 42 { 43 memset(s.a,0,sizeof(s.a)); 44 for(int i=1;i<=m;i++) 45 { 46 scanf("%d%d",&a,&b); 47 s.a[a][b]=1; 48 } 49 scanf("%d",&t); 50 for(int i=1;i<=t;i++) 51 { 52 scanf("%d%d%d",&a,&b,&k); 53 fuc(k,s); 54 printf("%d\n",c.a[a][b]); 55 } 56 } 57 }
以上是关于HDU 4686 - Arc of Dream的主要内容,如果未能解决你的问题,请参考以下文章