2019 南昌icpc网络赛 H. The Nth Item

题目链接

题意:F[0]=0 , F[1]=1 ; F[n]=3*F[n-1]+2*F[n-2] ; 输入 n1 和 q,让你计算结果ans,ans=F[n1]^F[n2]^......^F[nq] , 其中ni=n(i-1)^(A(i-1)*A(i-1)。Ai=F[n1]^......^F[ni]。

矩阵快速幂+记忆化

 然后这个题注意一下记忆化就行。

还有 tr1::unordered_mapmp 好像比 map mp 要快很多,因为 tr1::unordered_mapmp 是用哈希实现的,而map mp 是用红黑树实现的。(好像是快一个log)

AC代码:316ms

#include
#include 
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<mp;
struct mat
{
    ll a[2][2];
};
mat mat_mul(mat x,mat y)
{
    mat res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
                res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD;
    return res;
}
ll mat_pow(ll n)
{
    if(mp.count(n))
        return mp[n];
    ll nn=n;
    mat c,res;
    c.a[0][0]=3,c.a[0][1]=2,c.a[1][0]=1,c.a[1][1]=0;
    mem(res.a,0);
    for(int i=0;i<2;i++)
        res.a[i][i]=1;
    while(n)
    {
        if(n&1) res=mat_mul(res,c);
        c=mat_mul(c,c);
        n=n>>1;
    }
    mp[nn]=res.a[1][0]%MOD;
    return mp[nn];
}
int main()
{
    ll q,n;
    scanf("%lld%lld",&q,&n);
    ll ans=0;
    for(int i=1;i<=q;i++)
    {
        ll mm=mat_pow(n);
        ans=ans^mm;
        n=n^(mm*mm);
    }
    printf("%lld\n",ans);
    return 0;
}

 

你可能感兴趣的:(CCPC,ICPC题目)