2019南昌ICPC网络赛 H.The Nth Item(矩阵快速幂+欧拉降幂+数学处理)

在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

#define maxn 100005
#define ll long long
typedef pair<int,int> PII;
const int mod = 998244353;
const int modd = 998244352;        //素数欧拉降幂

struct Mat{
    ll m[3][3];
    Mat(){
        memset(m,0,sizeof(m));
    }
    inline void build(){
        for(int i=1;i<=2;i++)m[i][i]=1;
    }
}a;

Mat P[maxn],M[maxn];

Mat Mul(Mat x,Mat y){
    Mat c;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
            for(int k=1;k<=2;k++)
                c.m[j][i]=(c.m[j][i]+x.m[j][k]*y.m[k][i]%mod)%mod;
    return c;
}

Mat poww(Mat x,int y){
    Mat aa;aa.build();
    while(y){
        if(y&1)aa=Mul(aa,x);
        x=Mul(x,x);
        y>>=1;
    }
    return aa;
}

void init(){              //数学拆解
    P[0].build();
    for(int i=1;i<=1e5;i++)P[i]=Mul(P[i-1],a);
    M[0].build();
    for(int i=1;i<=1e5;i++)M[i]=Mul(M[i-1],P[100000]);
}

int main()
{
    int q;ll n,ans1,ans2;
    scanf("%d %lld",&q,&n);
    a.m[1][1]=3;a.m[2][1]=2;
    a.m[1][2]=1;a.m[2][2]=0;
    init();
    Mat ans=poww(a,(n-1)%modd);
    ans1=ans2=ans.m[1][1];
    ll x=n;
    int xx1,xx2;
    for(int i=2;i<=q;i++){
        x=x^(ans2*ans2);
        xx1=((x-1)%modd)/100000;
        xx2=((x-1)%modd)%100000;
        ans=Mul(M[xx1],P[xx2]);
        ans2=ans.m[1][1];
        ans1^=ans2;
    }
    printf("%lld",ans1);
}
原文地址:https://www.cnblogs.com/Mmasker/p/11917467.html