很显然这是矩阵快速幂的题
但发现用矩阵快速幂,指数很大很大,没办法用欧拉降幂(傻乎乎的用欧拉降幂,欧拉降幂只是对底数为整数,做了3个小时),结果是由周期的,根据周期对指数进行降幂,然后再矩阵快速幂,最后答案减一,因为这是求的向上取整
AC code:
#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; const int M = 2; typedef long long ll; int m=2; int MOD; struct Matrix{ ll matrix[M][M]; }; void init(Matrix &res) { for(int i=0;i<m;i++) { for(int j=0;j<m;j++) res.matrix[i][j]=0; res.matrix[i][i]=1; } } Matrix multiplicative(Matrix a,Matrix b) { Matrix res; memset(res.matrix,0,sizeof(res.matrix)); for(int i = 0 ; i <m; i++) for(int j = 0 ; j < m ; j++) for(int k = 0 ; k < m; k++) res.matrix[i][j] = (res.matrix[i][j]+a.matrix[i][k]%MOD*b.matrix[k][j]%MOD+MOD)%MOD; return res; } Matrix pow(Matrix mx,ll m) { Matrix res,base=mx; init(res); //初始为单位矩阵,即除主对角线都是1外,其他都是0 while(m) { if(m&1) res=multiplicative(res,base); base=multiplicative(base,base); m>>=1; } return res; } ll fast_pow(ll a,ll n,ll mod) { ll ans = 1; while(n) { if(n&1) ans = ans * a % mod; a = a*a % mod; n >>= 1; } return ans; } ll ans[N]; int looped[46337 + 10]; int getloop(int mod) { if(looped[mod]) return looped[mod]; ans[0] = 2%mod;ans[1] = 10%mod; for(int i = 2;;i++) { ans[i] = (ans[i - 1]*10ll%mod - ans[i - 2] + mod)%mod; // cout<<i<<endl; if(ans[i-1] == ans[0] && ans[i] == ans[1]) return looped[mod] = i - 1; } } int main() { int t,kase = 0,x; memset(looped,0,sizeof(looped)); scanf("%d",&t); while(t--) { scanf("%d%d",&x,&MOD); int loop = getloop(MOD); //cout<<loop<<endl; int n = (fast_pow(2,x,loop) + 1 ) % loop; ll a = 5; ll b = 24; //cout<<n<<endl; if(n == 0) printf("Case #%d: %lld\n",++kase,1%MOD); else if(n == 1) printf("Case #%d: %lld\n",++kase,(2*a-1)%MOD); else{ Matrix base={ 2*a,-(a*a-b), 1,0 }; base=pow(base,n-1); printf("Case #%d: %lld\n",++kase,(2*a%MOD*base.matrix[0][0]%MOD+2*base.matrix[0][1]%MOD+MOD - 1)%MOD); } } }
原文地址:https://www.cnblogs.com/lemon-jade/p/9736345.html
时间: 2024-11-08 20:36:40