2019 Nanchang Online Contest Problem H The Nth Item

线性递推函数的循环节是mod+1,但还是被卡时间,所以先把1-1e7中的F函数放到内存中,用矩阵快速幂提前处理出1e7~100e7的幂的特征矩阵,这样每次回答寻用只用O(1)的时间

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
const ll mod=998244353;
const ll Max=1e7;
ll FFF[Max+10];
mat mul(mat& A, mat& B){
    mat C(A.size(), vec(B[0].size()));
    for (int i = 0; i < A.size(); i++)
        for (int k = 0; k < B.size(); k++)
            if (A[i][k]) // 对稀疏矩阵的优化
                for (int j = 0; j < B[0].size(); j++)
                    C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod;
    return C;
}
mat Pow(mat A, ll n){
    mat B(A.size(), vec(A.size()));
    for (int i = 0; i < A.size(); i++) B[i][i] = 1;
    for (; n; n >>= 1, A = mul(A, A))
        if (n & 1) B = mul(B, A);
    return B;
}
mat MMM[110];
int main(){
    FFF[0]=0;FFF[1]=1;
    mat B(2,vec(2));
    B[0][0]=0;B[0][1]=2;B[1][0]=1;B[1][1]=3;
    for(int i=2;i<=Max;++i)FFF[i]=(FFF[i-1]*3+FFF[i-2]*2)%mod;
    for(ll i=1;i<=100;++i){MMM[i]=Pow(B,i*Max);}
    mat A(1,vec(2));
    int Q;ll n;cin>>Q>>n;
    int res=0;
    for(int i=1;i<=Q;++i){
        int x=n%(mod-1);
        if(x==0){
            res=res^0;
            n=n^0;
            break;
        }if(x==1){
            res=res^1;
            n=n^1;
            continue;
        }
        if(x<=Max){
            int ans=FFF[x];
            res=res^ans;
            n=n^(1ll*ans*ans);
            continue;
        }
        int y=x%Max;
        int z=x/Max;
        int ans=(1ll*MMM[z][0][1]*FFF[y-1]+MMM[z][1][1]*FFF[y])%mod;
        res=res^ans;
        n=n^(1ll*ans*ans);
    }
    cout<<res<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值