2326: [HNOI2011]数学作业
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1648 Solved: 972
Description
(f[n])(10^k 1 1)(f[n-1])
( n )=(0 1 1)( n-1 )
( 1 ) (0 0 1)( 1 )
然后分段矩阵乘法。这道题调了整整一晚上,忘记每一步运算都取模,这道题很容易超过long long。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long using namespace std; ll n,m; struct matrix { ll f[4][4]; matrix(){memset(f,0,sizeof(f));} friend matrix operator *(const matrix &a,const matrix &b) { matrix c; F(i,1,3) F(j,1,3) F(k,1,3) c.f[i][j]=(c.f[i][j]%m+a.f[i][k]%m*b.f[k][j]%m)%m; return c; } }ans,tmp; inline void calc(ll t,ll x) { memset(tmp.f,0,sizeof(tmp.f)); tmp.f[1][1]=t%m; tmp.f[1][2]=tmp.f[1][3]=tmp.f[2][2]=tmp.f[2][3]=tmp.f[3][3]=1; for(ll y=x-t/10+1;y;y>>=1,tmp=tmp*tmp) if (y&1) ans=tmp*ans; } int main() { scanf("%lld%lld",&n,&m); memset(ans.f,0,sizeof(ans.f)); F(i,1,3) ans.f[i][i]=1; ll t=10; while (n>=t) { calc(t,t-1); t*=10; } calc(t,n); printf("%lld\n",ans.f[1][3]); return 0; }
时间: 2024-10-10 05:31:52