BZOJ3328: PYXFIB

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3328

题解:关键在于只处理i%k的项,那么我们就需要用一个式子来表达这个东西。

        p%k==1.会让我们想到NTT的w=power(g,(p-1)/k)。而w的性质就是w^i=1%p当且仅当i%k=0。g是p的一个原根。
        

        所以sigma(w^i)(0<=i<k)=0 

        然后我们构造一个A[x]=x^(-n)*(I*x+T)^n  其中I是单位矩阵,T是fib矩阵。

        然后做A[W^0],A[W^-1]……A[W^-K+1]求和左上角就是K*ans。  

        因为sigma(w^ij)(0<=i<k)=k[j%k==0]

        构造技巧实在太科幻,不愧是业界毒瘤出的题。

代码:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 10000+5
 14 #define maxm 10000000
 15 #define eps 1e-10
 16 #define ll long long
 17 #define pa pair<int,int>
 18 #define for0(i,n) for(int i=0;i<=(n);i++)
 19 #define for1(i,n) for(int i=1;i<=(n);i++)
 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 23 #define lch t[k].l,l,mid
 24 #define rch t[k].r,mid+1,r
 25 using namespace std;
 26 inline ll read()
 27 {
 28     ll x=0,f=1;char ch=getchar();
 29     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 30     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 31     return x*f;
 32 }
 33 struct matrix
 34 {
 35     int d[3][3];
 36 };
 37 matrix A,I,T,ans;
 38 ll n;
 39 int p,k,g,w,pr[maxn];
 40 inline void print(matrix a)
 41 {
 42     for1(i,2)for1(j,2)printf("%d%c",a.d[i][j],j==2?'\n':' ');
 43 }
 44 matrix operator *(matrix a,matrix b)
 45 {
 46     matrix c=A;
 47     for1(i,2)for1(j,2)for1(k,2)(c.d[i][j]+=(ll)a.d[i][k]*b.d[k][j]%p)%p;
 48     return c;
 49 }
 50 matrix operator +(matrix a,matrix b)
 51 {
 52     matrix c;
 53     for1(i,2)for1(j,2)c.d[i][j]=(a.d[i][j]+b.d[i][j])%p;
 54     return c;
 55 }
 56 matrix operator *(matrix a,int  b)
 57 {
 58     matrix c;
 59     for1(i,2)for1(j,2)c.d[i][j]=(ll)a.d[i][j]*b%p;
 60     return c;
 61 }
 62 inline int power(int x,int y)
 63 {
 64     int t=1;
 65     for(;y;y>>=1,x=(ll)x*x%p)
 66      if(y&1)t=(ll)t*x%p;
 67     return t;
 68 }
 69 inline matrix power(matrix x,ll y)
 70 {
 71     matrix t=I;
 72     for(;y;y>>=1,x=x*x)
 73      if(y&1)t=t*x;
 74     return t;
 75 }
 76 inline int gen()
 77 {
 78     int t=p-1,x=sqrt(t);pr[0]=0;
 79     for2(i,2,x)if(t%i==0)
 80     {
 81         pr[++pr[0]]=i;
 82         while(t%i==0)t/=i;
 83     }
 84     if(t>1)pr[++pr[0]]=t;
 85     for2(i,2,inf)
 86     {
 87         bool flag=0;
 88         for1(j,pr[0])if(power(i,(p-1)/pr[j])==1){flag=1;break;}
 89         if(!flag)return i;
 90     }
 91 }
 92 int main()
 93 {
 94     freopen("input.txt","r",stdin);
 95     freopen("output.txt","w",stdout);
 96     I.d[1][1]=I.d[2][2]=1;
 97     T.d[1][1]=T.d[1][2]=T.d[2][1]=1;
 98     int cs=read();
 99     while(cs--)
100     {
101         n=read();k=read();p=read();g=gen();w=power(g,(p-1)/k);ans=A;
102         for3(i,0,-k+1)
103         {
104           int x=power(w,k+i);
105           ans=ans+power(I*x+T,n)*power(x,((-n)%k+k)%k);
106         }
107         cout<<(ll)ans.d[1][1]*power(k,p-2)%p<<endl;
108     }    
109     return 0;
110 }
View Code

 

posted @ 2015-04-02 18:19 ZYF-ZYF Views(...) Comments(...) Edit 收藏