BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)
生活随笔
收集整理的這篇文章主要介紹了
BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
3240: [Noi2013]矩陣游戲
Time Limit:?10 Sec?? Memory Limit:?256 MBSubmit:?123?? Solved:?73
[ Submit][ Status]
Description
婷婷是個喜歡矩陣的小朋友,有一天她想用電腦生成一個巨大的n行m列的矩陣(你不用擔心她如何存儲)。她生成的這個矩陣滿足一個神奇的性質:若用F[i][j]來表示矩陣中第i行第j列的元素,則F[i][j]滿足下面的遞推式:
F[1][1]=1
F[i,j]=a*F[i][j-1]+b (j!=1)
F[i,1]=c*F[i-1][m]+d (i!=1)
遞推式中a,b,c,d都是給定的常數。
現在婷婷想知道F[n][m]的值是多少,請你幫助她。由于最終結果可能很大,你只需要輸出F[n][m]除以1,000,000,007的余數。
Input
一行有六個整數n,m,a,b,c,d。意義如題所述
Output
包含一個整數,表示F[n][m]除以1,000,000,007的余數
Sample Input
3 4 1 3 2 6Sample Output
85HINT
?
樣例中的矩陣為:
1 4 7 10
26 29 32 35
76 79 82 85
?
?
Source
?
?
NOI賽場上拿了70分(沒用費馬小定理)
PS:實際原因是沒算復雜度囧。。。。
好吧。。。這題讓我們回顧一下費馬小定理:
a^b mod (phi(p))=1 (mod p)
所以可以mod ,特判a=c=1的特殊情況
?
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (1000000007) #define MAXN (1000000+10) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; ll a,b,c,d,n,m,phiF; ll getint(char s[]) //_dec_1 {char c;ll x=0;for(int i=0,c=s[i];s[i];c=s[++i]){x=(x*10+c-48)%phiF;}x=(x-1+phiF)%phiF;return x; } struct M {int n,m;ll a[3][3];M(){n=m=2;MEM(a);}M(ll a1,ll a2,ll b1,ll b2){n=m=2;MEM(a) a[1][1]=a1,a[1][2]=a2,a[2][1]=b1,a[2][2]=b2; }friend M operator*(M a,M b){M c;For(k,2)For(i,2)For(j,2)c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F;/*For(i,2){For(j,2) cout<<c.a[i][j]<<' ';cout<<endl;}*/return c; }void make_I(){n=m=2;MEM(a)For(i,n) a[i][i]=1;} }A,B,C,D,I; void print(M a) {For(i,2){For(j,2) cout<<a.a[i][j]<<' ';cout<<endl;} } M pow2(M a,ll b) {M c=I;static bool a2[MAXN];int n=0;while (b) a2[++n]=b&1,b>>=1;For(i,n){if (a2[i]) c=c*a;a=a*a;}return c; } char s1[MAXN],s2[MAXN]; int main() {scanf("%s%s",s1,s2);scanf("%lld%lld%lld%lld",&a,&b,&c,&d);if (a==1&&c==1) phiF=F;else phiF=F-1;n=getint(s1);m=getint(s2);A=M(a,b,0,1);B=M(c,d,0,1);I=M(1,0,0,1);C=pow2(A,m);//print(C);D=B*C;//print(D);D=pow2(D,n);D=C*D;//print(D);cout<<(D.a[1][2]+D.a[1][1])%F<<endl;return 0; }
順便再附一份讀文件的特殊寫法:
?
?
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (1000000007) #define MAXN (1000000+10) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; ll a,b,c,d,n,m,phiF; ll getint() //_dec_1 {char c;while (c=getchar(),(!isdigit(c)));//cout<<(int)c;ll x=c-48;while (c=getchar(),(isdigit(c))){x=(x*10+c-48)%phiF;}x=(x-1+phiF)%phiF;return x; } struct M {int n,m;ll a[3][3];M(){n=m=2;MEM(a);}M(ll a1,ll a2,ll b1,ll b2){n=m=2;MEM(a) a[1][1]=a1,a[1][2]=a2,a[2][1]=b1,a[2][2]=b2; }friend M operator*(M a,M b){M c;For(k,2)For(i,2)For(j,2)c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F;/*For(i,2){For(j,2) cout<<c.a[i][j]<<' ';cout<<endl;}*/return c; }void make_I(){n=m=2;MEM(a)For(i,n) a[i][i]=1;} }A,B,C,D,I; void print(M a) {For(i,2){For(j,2) cout<<a.a[i][j]<<' ';cout<<endl;} } M pow2(M a,ll b) {M c=I;static bool a2[MAXN];int n=0;while (b) a2[++n]=b&1,b>>=1;For(i,n){if (a2[i]) c=c*a;a=a*a;}return c; }int main() {freopen("matrix.in","r",stdin);freopen("matrix.out","w",stdout);scanf("%*s%*s");scanf("%lld%lld%lld%lld",&a,&b,&c,&d);if (a==1&&c==1) phiF=F;else phiF=F-1;freopen("matrix.in","r",stdin);n=getint();m=getint();A=M(a,b,0,1);B=M(c,d,0,1);I=M(1,0,0,1);C=pow2(A,m);//print(C);D=B*C;//print(D);D=pow2(D,n);D=C*D;//print(D);cout<<(D.a[1][2]+D.a[1][1])%F<<endl;return 0; }?
?
總結
以上是生活随笔為你收集整理的BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: menuItem无法响应点击事件
- 下一篇: 自定义webpart显示Lync状态球