The Nth Item

题目描述    传送门

For a series FFF:

We have some queries. For each query N, the answer A is the value F(N) modulo 998244353.

Moreover, the input data is given in the form of encryption, only the number of queries Q and the first query N1​ are given. For the others, the query Ni(2≤i≤Q) is defined as the xor of the previous Ni and the square of the previous answer Ai−1​. For example, if the first query N1​ is 2, the answer A1 is 3, then the second query N2​ is 2 xor (3∗3)=11.

Finally, you don't need to output all the answers for every query, you just need to output the xor of each query's answer A1 xor A2...xor AQ​.

Input

The input contains two integers,Q, N, 1 ≤ Q≤10^7, 0 ≤ N≤10^18. Q representing the number of queries and N representing the first query.

Output:

An integer representing the final answer.

样例输入

17 473844410

样例输出

903193081

思路:矩阵快速幂 + map,  正在这些F(N) Mod 998244353  的结果是有一定的循环的(猜想),但是其周期不好把握。于是我就用了这个map 把算过的F(N) 记录下来,下次再用的时候可以直接使用,而不用再调用矩阵快速幂了。这样就节省了不少时间。顺利AC。

 

AC代码

#include <bits/stdc++.h>

using namespace std;
#define io ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mset(a, n) memset(a, n, sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<int,PII> PPI;
typedef pair<ll, ll> PLL;
const int maxn =  2e5+5;
const ll Mod = 998244353;

ll Q, N;
map<ll, ll> ma;
struct Mat{    // 2X2 的矩阵
    ll x0, x1, x2, x3;
};

Mat mul(Mat A, Mat B){  // C = A*B
    Mat C;
    C.x0 = ( (A.x0*B.x0%Mod + A.x1*B.x2%Mod)%Mod );
    C.x1 = ( (A.x0*B.x1%Mod + A.x1*B.x3%Mod)%Mod );
    C.x2 = ( (A.x2*B.x0%Mod + A.x3*B.x2%Mod)%Mod );
    C.x3 = ( (A.x2*B.x1%Mod + A.x3*B.x3%Mod)%Mod );

    return C;
}

Mat Qpow(Mat A, ll mi){
    Mat res0; res0.x0 = (1), res0.x1 = (0), res0.x2 = (0), res0.x3 = (1);
    while(mi>0){
        if(mi&1){
            res0 = mul(res0, A);
        }
        A = mul(A, A);
        mi>>=1;
    }
    return res0;
}

int main(){
    cin>>Q>>N;
    ll ans = 0, A0;
    Mat A; A.x0=3, A.x1 = 2, A.x2 = 1, A.x3 = 0;
    Mat res;
    for(int i = 1;i<=Q; i++){

        if(ma[N] == 0){     // 优化在这里
            res = Qpow(A, N-1ll);
            A0 = res.x0;
            ma[N] = A0;
        }
        else res.x0 = ma[N];

        N = N^(A0*A0);
        ans ^= A0;
    }
    cout<<ans<<'\n';
    return 0;
}
/*
170000 473844410
*/

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值