HDU 3802Ipad,IPhone

前两块可以看成是不是二次剩余,快速幂计算即可。

后半部分可以看成x1=a+b+2ab,x2=a+b-2ab为特征方程x^2-px-qx=0的两根

然后可以通过韦达定理求出p和q,因此递推式为A(n+2)=pA(n+1)+qA(n)

还要用费马小定理化简一下斐波那契数。

矩阵快速幂即可求。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll mod;
 5 struct Max
 6 {
 7     ll a[4][4];int n,m;
 8     Max(){n=m=0;memset(a,0,sizeof(a));};
 9     Max operator *(const Max &b)const{
10         Max c;c.n=n;c.m=b.m;
11         for(int k=0;k<m;++k)
12         for(int i=0;i<n;++i)
13         for(int j=0;j<b.m;++j)
14         c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
15         return c;
16     }
17 };
18 ll qmod(ll n,ll m,ll p)
19 {
20     ll ans=1;
21     while(m)
22     {
23         if(m&1)ans=ans*n%p;
24         n=n*n%p;m>>=1;
25     }
26     return ans;
27 }
28 Max Qmod(Max a,ll b)
29 {
30     Max ans;ans.n=a.n;ans.m=a.m;
31     ans.a[0][0]=ans.a[1][1]=1;
32     while(b)
33     {
34         if(b&1)ans=ans*a;
35         a=a*a;b>>=1;
36     }
37     return ans;
38 }
39 ll calc(ll a,ll b,ll n,ll p)
40 {
41     mod=p-1;
42     Max f;f.n=f.m=2;
43     f.a[0][0]=1;f.a[0][1]=1;
44     f.a[1][0]=1;f.a[1][1]=0;
45     f=Qmod(f,n);
46     mod=p;
47     int k=f.a[0][0];
48     Max z;z.n=z.m=2;
49     z.a[0][0]=2*(a+b)%mod;z.a[1][0]=-(a-b)*(a-b)%mod;
50     z.a[0][1]=1;z.a[1][1]=0;
51     z=Qmod(z,k-1);
52     Max ans;ans.n=1,ans.m=2;
53     ans.a[0][1]=2,ans.a[0][0]=2*(a+b)%mod;
54     ans=ans*z;
55     return (ans.a[0][0]+mod)%mod;
56 }
57 int main()
58 {
59     int T;ll a,b,n,p;
60     scanf("%d",&T);
61     while(T--)
62     {
63         scanf("%lld%lld%lld%lld",&a,&b,&n,&p);
64         int tmp1=qmod(a,(p-1)/2,p);
65         int tmp2=qmod(b,(p-1)/2,p);
66         if(tmp1==-1||tmp2==-1)
67         {
68             puts("0");continue;
69         }tmp1++;tmp2++;
70         printf("%lld\n",tmp1%p*tmp2%p*calc(a,b,n,p)%p);
71     }
72     return 0;
73 }

 

posted @ 2018-02-27 17:49  大奕哥&VANE  阅读(220)  评论(0编辑  收藏  举报