题目链接:
http://acm.zju.edu.cn/changsha/showContestProblem.do?problemId=19
题目意思:
题目很晦涩。在k维空间,开始长度为l,操作一次变为l+√(l*(l+1)).问最后%k还剩下的整数是多少。
解题思路:
数学公式+矩阵快速幂。
因为是在k维空间,所以也就是要求(l+√(l*(l-1))^k向下取整后%k的值。
这题和今年长沙邀请赛的A题,差不多,只不过那题是向上取整,这题是向下取整,减一就行了。
思路参考hdu 4565
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 3 ll m,a,b; struct Mar { int r,c; ll sa[Maxn][Maxn]; void init(int a,int b) { r=a,c=b; memset(sa,0,sizeof(sa)); } }; Mar operator *(struct Mar & a,struct Mar & b) { Mar c; c.init(a.r,b.c); for(int k=1;k<=a.c;k++) { for(int i=1;i<=c.r;i++) { if(!a.sa[i][k]) continue; for(int j=1;j<=c.c;j++) { if(!b.sa[k][j]) continue; c.sa[i][j]=(c.sa[i][j]+a.sa[i][k]*b.sa[k][j])%m; } } } return c; } Mar ba[35],ans; void init() { ba[0].init(2,2); ba[0].sa[1][1]=(2*a)%m,ba[0].sa[1][2]=((b-a*a)%m+m)%m; ba[0].sa[2][1]=1,ba[0].sa[2][2]=0; for(int i=1;i<32;i++) //2^i { ba[i]=ba[i-1]*ba[i-1]; } } int main() { ll l,k; while(~scanf("%lld%lld",&k,&l)) { a=l,b=l*(l-1); m=k; init(); ans.init(2,1); ans.sa[1][1]=(2*a)%m,ans.sa[2][1]=2; for(int i=0;i<32&&k;i++) { if(k&1) { ans=ba[i]*ans; } k>>=1; } printf("%lld\n",(ans.sa[2][1]-1+m)%m); } return 0; }