hdu 5451 Best Solver 矩阵循环群+矩阵快速幂
生活随笔
收集整理的這篇文章主要介紹了
hdu 5451 Best Solver 矩阵循环群+矩阵快速幂
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://acm.hdu.edu.cn/showproblem.php?pid=5451
題意:給定x? ? 求解
思路: 由斐波那契數列的兩種表示方法, 之后可以轉化為 線性表示 F[n] = F[n-1] + F[n-2] ;
同時可以看出 ? 和 是 一元二次方程的兩根, a? = 1, b = -1 又是之后遞推式的系數;
同理這里需要構造出兩根為 和 ,這時 a = 1, b = –10 得 F[n] = 10F[n-1] – F[n-2]; (當然可以直接打表遞推出關系式)
?
如果不管指數,看成是一個?? 這道題將變成 hdu 2256 Problem of Precision
之后需要知道如何對指數 進行取模簡化,問題是具體Mod 多少?
套路是mod (M-1)*(M+1) ,具體證明詳見:http://blog.csdn.net/acdreamers/article/details/25616461
到這里指數取模之后,之后跑矩陣快速冪即可;
?
細節: 前面矩陣快速冪原本只是跑指數-1次,正好把1抵消了;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define pb push_back #define MK make_pair #define A first #define B second #define clear0 (0xFFFFFFFE) #define inf 0x3f3f3f3f #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) #define bitnum(a) __builtin_popcount(a) #define lowbit(x) (x&(-x)) #define K(x) ((x)*(x)) typedef pair<int,int> PII; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; template<typename T> void read1(T &m) {T x = 0,f = 1;char ch = getchar();while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) {if(a>9) out(a/10);putchar(a%10+'0'); } inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); } inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; } template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;} template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;} int mod; struct Matrix{int row, col;ll m[10][10];Matrix(int r,int c):row(r),col(c){ memset(m, 0, sizeof(m)); }bool unitMatrix(){if(row != col) return false;for(int i = 0;i < row;i++) //方陣才有單位矩陣;m[i][i] = 1;return true;}Matrix operator *(const Matrix& t){Matrix res(row, t.col);for(int i = 0; i < row; i++)for(int j = 0;j < t.col;j++)for(int k = 0; k < col; k++)res.m[i][j] = (res.m[i][j] + m[i][k]*t.m[k][j])% mod;return res;}void print(){for(int i = 0;i < row; i++){for(int j = 0;j < col; j++)printf("%lld ",m[i][j]);puts("");}} };Matrix pow(Matrix a, ll n) {Matrix res(a.row, a.col);res.unitMatrix();while(n){if(n & 1) res = res*a;a = a*a;n >>= 1;}return res; } ll POW(ll a,int n, ll mod) {ll ans = 1;while(n){if(n&1) ans = (ans*a)%mod;a = a*a%mod;n >>= 1;}return ans; } int main() {//freopen("data.txt","r",stdin);//freopen("out.txt","w",stdout);Matrix mat(2,2);mat.m[0][0] = 5, mat.m[0][1] = 12;mat.m[1][0] = 2, mat.m[1][1] = 5;int T, kase = 1;scanf("%d",&T);while(T--){int n;read2(n, mod);ll MOD = 1LL*(mod-1)*(mod+1);MOD = POW(2,n,MOD);Matrix res = pow(mat, MOD);//res.print();Matrix tmp(2,1);tmp.m[0][0] = 5, tmp.m[1][0] = 2;res = res*tmp;printf("Case #%d: %d\n",kase++, (2*res.m[0][0]-1)% mod);}return 0; }?
ps: 這道題循環節較小,直接求解循環節也可以A;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define pb push_back #define MK make_pair #define A first #define B second #define clear0 (0xFFFFFFFE) #define inf 0x3f3f3f3f #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) #define bitnum(a) __builtin_popcount(a) #define lowbit(x) (x&(-x)) #define K(x) ((x)*(x)) typedef pair<int,int> PII; typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; template<typename T> void read1(T &m) {T x = 0,f = 1;char ch = getchar();while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) {if(a>9) out(a/10);putchar(a%10+'0'); } inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); } template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;} template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}ll pow(ll a,uint n,int mod) {ll ans = 1;while(n){if(n&1) ans = (ans*a)%mod;a = a*a%mod;n >>= 1;}return ans; } const int maxn = 463370; int F[maxn]; int main() {//freopen("data.txt","r",stdin);//freopen("out.txt","w",stdout);int T, kase = 1;/*double d1 = 5+2*sqrt(6), d2 = 5 - 2*sqrt(6);rep1(i,1,10){printf("%.5f\n",pow(d1,i)+pow(d2,i));}*/scanf("%d",&T);while(T--){uint x, mod;read2(x,mod);F[0] = 10%mod, F[1] = 98%mod;ll cycle = -1;for(int i = 2; ; i++){F[i] = (10*F[i-1] - F[i-2]+ mod)% mod;if(F[i] == F[1] && F[i-1] == F[0]){cycle = i-1;break;}}int p = pow(2,x, cycle);printf("Case #%d: %d\n",kase++, F[p]-1);}return 0; } View Code?
轉載于:https://www.cnblogs.com/hxer/p/5724436.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的hdu 5451 Best Solver 矩阵循环群+矩阵快速幂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深圳特诺卖酒被骗怎么办
- 下一篇: JavaScript之共享onload