现在的位置: 首页 > 综合 > 正文

hdu4291 A Short problem

2018年04月23日 ⁄ 综合 ⁄ 共 1135字 ⁄ 字号 评论关闭

完全被虐啊,见识太少,完全没有意识到取模必定会有循环节的问题,所以束手无策。。。。。

先暴力本地算出最外层取模的循环节,在依次往里推循环节,还需要注意两个long long型相乘的溢出问题,不过这道题好像没有这么极端的数据

code:

#include <cstdio>
#include <cstring>
#define LL __int64
using namespace std;
LL modular_multi(LL a, LL b, LL c) {
    LL res;
    res = 0;
    while (b) {
        if (b & 1) {
            res += a;
            if (res >= c) {
                res -= c;
            }
        }
        a <<= 1;
        if (a >= c) {
            a -= c;
        }
        b >>= 1;
    }
    return res;
}
struct Matrix
{
    LL Mat[2][2];
    void init()
    {
        memset(Mat,0,sizeof(Mat));
    }
    void unit()
    {
        init();
        Mat[0][0]=Mat[1][1]=1;
    }
    Matrix()
    {
        init();
    }
    Matrix Mul(Matrix b,LL mod)
    {
        Matrix res;
        res.init();
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
            {
                for(int k=0;k<2;k++)
                {
                    res.Mat[i][j]=(res.Mat[i][j] + modular_multi(Mat[i][k],b.Mat[k][j],mod)) %mod;
                }
            }
        }
        return res;
    }
    Matrix Pow(LL exp,LL mod)
    {
        Matrix tmp=*this,res;
        res.unit();
        while(exp)
        {
            if( exp&1)
            {
                res=res.Mul(tmp,mod);
            }
            exp >>= 1;
            tmp=tmp.Mul(tmp,mod);
        }
        return res;
    }
    void Print()
    {
        puts("------------------");
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
            {
                printf(" %I64d",Mat[i][j]);
            }
            puts("");
        }
    }
}a;
LL solve(LL n,LL mod)
{
    if(n==0)
    {
        return 0;
    }
    return a.Pow(n-1,mod).Mat[0][0];
}
int main()
{
    LL n,ans;
    a.Mat[0][0]=3;
    a.Mat[0][1]=1;
    a.Mat[1][0]=1;
    a.Mat[1][1]=0;
    while(~scanf("%I64d",&n))
    {
        ans=solve(solve(solve(n,183120),222222224),1000000007);
        printf("%I64d\n",ans);
    }
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.