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
",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 ",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 ",kase++, F[p]-1); } return 0; }