The 2019 Asia Nanchang[網絡賽]——H

問題蟲洞: The Nth Item

 

黑洞內窺:

BZ比較lan~~~~~~~

 

思維光年:

找出mod998244353的循環節,然後矩陣快速冪暴力。。

然而, 我並沒有找到mod的循環節,所以,,

矩陣快速冪暴力會t。。。。。

這時候我們可以大膽假設,如果p>5000,就異或完了所有的Ai。

然後莽。。。。。。就完(AC)了,(其實是數據太水了~~~)

 

理性的思考:

其實這個公式我們知道,但是感覺沒niao用~~~~所以就用矩陣快速冪了~~~

 

ACcode:

#include  <stdio.h>
#include <iostream>
#include<algorithm>
#include      <set>
#include      <map>
#include    <queue>
#include    <stack>
#include   <string>
#include   <math.h>
#include   <vector>
#include  <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 1000005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
const ll mod = 998244353;
#define mem(a, b) memset(a, b, sizeof(a))

struct mat
{
    ll m[4][4];
};

mat mul(mat a, mat b)
{
    mat res;
    for(int i=0; i<4; ++i)
        for(int j=0; j<4; ++j)
            res.m[i][j] = 0;
    for(int i=1; i<=2; ++i)
        for(int j=1; j<=2; ++j)
            for(int k=1; k<=2; ++k)
                res.m[i][k] = (res.m[i][k] + a.m[i][j]*b.m[j][k])%mod;
    return res;
}

mat pow(mat a, int b)
{
    mat ans;
    memset(ans.m, 0, sizeof(ans.m));
    ans.m[1][1] = ans.m[2][2] = 1;
    while(b)
    {
        if(b&1)
            ans = mul(ans, a);
        a = mul(a, a);
        b >>= 1;
    }
    return ans;
}

ll getF(ll s)
{
    ll mod, a, b, x0, x1;
    char n[105];
    int len = 0;
    while(s/10)
    {
        n[len++] = s%10+48;
        s/=10;
    }
    n[len++] = s+48;
    reverse(n, n+len);
    
    x0=0, x1=1, a=3, b=2, mod=998244353;
    mat ans, ori;
    mem(ans.m, 0);
    mem(ori.m, 0);
    ori.m[1][2] = 1, ori.m[2][1] = b, ori.m[2][2] = a;
    ans.m[1][1] = 1, ans.m[2][2] = 1;
    for(int i = len-1; i>=0; --i) 
    {
        mat t = pow(ori, n[i]-'0');
        ans = mul(ans, t);
        ori = pow(ori, 10);
    }
    return (x0*ans.m[1][1]+x1*ans.m[1][2])%mod;
}

int main()
{
    ll q, n;
    scanf("%lld %lld", &q, &n);
    ll ans = getF(n);
    ll xi = n^(ans*ans);
    ll sum=ans;
    if(q > 50000) q = 50000;
    for(int i=2; i<=q; ++i)
    {
        ans = getF(xi);
        sum^=ans;
        xi = xi^(ans*ans);
    }
    cout << sum << '\n';
    return 0;
}

 

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