这题用矩阵乘法,但是我们会发现,如果用m膜的话,很明显爆longlong。
怎么办呢,我想了一个比较傻的做法,就是直接用g来膜。
结果呢,wa了。这是为什么呢。
举个例子:
m=5,g=4;
ans=10%5%4=0。
如果直接用g膜。
ans=10%4=2。
很显然,wa定了。
我看到一个做法,感觉很强
就是:
ans=x*y.可以转换成
ans=x*(y/2)*2,if(y%2==1)ans+=x;
这样我们就可以递归下去在递归的过程中膜m就好了。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define For(i,a,b) for(int i=a;i<=b;i++) using namespace std; long long mod,a,c,x,n,g; struct Yzyet{long long p[2][2];}ans,yzy; long long mul(long long x,long long y){ if(!y)return 0; long long ans=mul(x,y>>1)<<1; if(y&1)ans+=x; ans%=mod; return ans; } inline Yzyet operator *(const Yzyet a,const Yzyet b){ Yzyet c;memset(c.p,0,sizeof(c.p)); For(i,0,1)For(k,0,1) if(a.p[i][k])For(j,0,1) c.p[i][j]=(c.p[i][j]+mul(a.p[i][k],b.p[k][j]))%mod; return c; } void init(){ ans.p[0][0]=x;ans.p[0][1]=1;ans.p[1][0]=ans.p[1][1]=0; yzy.p[0][0]=a;yzy.p[0][1]=0;yzy.p[1][0]=c;yzy.p[1][1]=1; } void ksm(long long n){ while(n){ if(n&1)ans=ans*yzy; yzy=yzy*yzy;n>>=1; } } int main() { scanf("%lld%lld%lld%lld%lld%lld",&mod,&a,&c,&x,&n,&g); init();ksm(n);printf("%d\n",ans.p[0][0]%g); return 0; }
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。