设为首页 加入收藏

TOP

hdu-4656-So Easy!-递推式+矩阵优化
2015-07-24 05:45:16 来源: 作者: 【 】 浏览:4
Tags:hdu-4656-So Easy 矩阵 优化

?

?

题意非常简单, a,b,n 都是正整数,求

Sn=?(a+b√)n?%m,(a?1)2

这个题目也是2008年Google Codejam Round 1A的C题。

做法其实非常简单,记 (a+b√)n An ,配项

Cn=An+Bn=(a+b√)n+(a?b√)n

两项恰好共轭,所以 Cn 是整数。又根据限制条件

(a?1)2

也就是说 Cn=?An?

Sn=(Cn)%m

Cn 的方法是递推。 对 Cn 乘以 (a+b√)+(a?b√)

于是

Cn+1=2aCn?(a2?b)Cn?1

把这个递推式写成矩阵形式

[Cn+1Cn]=[2a1?(a2?b)0][CnCn?1]

于是就可以用矩阵快速幂来做了

[Cn+1Cn]=[2a1?(a2?b)0]n[C1C0]

---------------------------------------------------------------------------- 以上是原版的题解。 这个题目是我做训练赛的时候做到的,当时没做出来,后来看题解,一开始不明白为什么C[N]=[ A[N] ]; 后来的时候百度了一下共轭的定义发现: C[N]一定是一个整数。 B[N]又小于1. 所以 C[N]=[ A[N] ]=A[N]+B[N];

#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include
          #include 
          
            using namespace std; #define maxn 3001 #define LL long long struct matrix { LL mat[3][3]; matrix() { memset(mat,0,sizeof(mat)); } }; int m; matrix mul(matrix A,matrix B) { matrix C; for(int i=1;i<=2;i++) { for(int j=1;j<=2;j++) { C.mat[i][j]=0; for(int k=1;k<=2;k++) { C.mat[i][j]+=A.mat[i][k]*B.mat[k][j]; } C.mat[i][j]%=m; if(C.mat[i][j]<0)C.mat[i][j]+=m; } } return C; } matrix pows(matrix A,LL p) { matrix B; B.mat[1][1]=B.mat[2][2]=1; while(p) { if(p&1)B=mul(B,A); A=mul(A,A); p>>=1; } return B; } int main() { int a,b,n; while(~scanf(%d%d%d%d,&a,&b,&n,&m)) { matrix A; A.mat[1][1]=2; A.mat[2][1]=2*a; matrix B; B.mat[1][1]=0; B.mat[1][2]=1; B.mat[2][1]=b-a*a; B.mat[2][2]=2*a; B=pows(B,n); A=mul(B,A); cout<
           
            

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇ZOJ1610 Count the Colors 经典线.. 下一篇UVA 10557 XYZZY

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: