数学公式+矩阵快速幂-2013 ACM/ICPC Asia Regional Changsha Online H 题

来源:互联网 发布:手机淘宝看自己的评价 编辑:程序博客网 时间:2024/06/09 20:28

题目链接:

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 3ll 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;}


原创粉丝点击