2019 南昌網絡賽 H-The Nth Item

題目鏈接:https://nanti.jisuanke.com/t/41355

分段打表。。

將一個ll整數分成三部分:

123456789123456789:123456   789123   456789

將這三部分的矩陣冪分別預處理出來。

很秀的打表方法。。。。

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=2,mod=998244353 ;
const int N=1e6;
struct Matrix
{
	ll mat[MAXN][MAXN];
	Matrix() {}
	Matrix operator*(Matrix const &b)const
	{
		Matrix res;
		memset(res.mat, 0, sizeof(res.mat));
		for (int i = 0 ;i < MAXN; i++)
		for (int j = 0; j < MAXN; j++)
		for (int k = 0; k < MAXN; k++)
			res.mat[i][j] = (res.mat[i][j]+this->mat[i][k] * b.mat[k][j])%mod;
		return res;
	}
};
Matrix pre[4][2*N+10];
Matrix base,fi;
ll f(ll n)
{
    if(n<=1) return n;
    n--;
    int ty=0;int f=0;
    Matrix ans;
    while(n&&ty<3)
    {
        ++ty;
        ll k=n%N;
        if(ty==3) k=n;
        if(k)
        {
            if(f) ans=ans*pre[ty][k];
            else ans=pre[ty][k];
            f=1;
        }
        n/=N;
    }
    return ans.mat[0][0];
}
void init()
{
    base.mat[0][0] = 3;
	base.mat[0][1] = 2;
	base.mat[1][0] = 1;
	pre[1][1]=base;
	for(int i=2;i<=N;++i) pre[1][i]=pre[1][i-1]*pre[1][1];
	pre[2][1]=pre[1][N];
	for(int i=2;i<=N;++i) pre[2][i]=pre[2][i-1]*pre[2][1];
	pre[3][1]=pre[2][N];
	for(int i=2;i<=2*N;++i) pre[3][i]=pre[3][i-1]*pre[3][1];
}

int main()
{
    init();
	int q;
	ll n;
	scanf("%d%lld",&q,&n);
    ll t=0,a;
    for(int i=1;i<=q;i++)
    {
        a=f(n);
        n=n^(a*a);
        t^=a;
    }
    printf("%lld\n",t);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章