标签:map inline 斐波那契数列 res order using while 数列 include
给出递推式 \(F\):
给出查询次数:\(Q\) 和第一次查询的数 \(N\),每次查询的答案为:\(A_i=F(N)\)。并且\(N_i=N_{i-1}\ xor\ A_{i-1}^2\),最后要求输出:\(A_1\ xor\ A_2 ...\ xor\ A_Q\)。
题目链接:https://nanti.jisuanke.com/t/41355
(1) \(N\) 的范围很大,直接算肯定算不出来,但因为数据比较水,所以用 \(map\) 记忆化一下就可以。
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
typedef long long ll;
unordered_map<ll,ll>mp;
struct matrix
{
ll mat[3][3];
void zero()
{
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
mat[i][j]=0;
}
void eye()
{
for(int i=1;i<=2;i++)
mat[i][i]=1;
}
matrix operator * (const matrix &mt)const
{
matrix res;
res.zero();
for(int i=1;i<=2;i++)
{
for(int k=1;k<=2;k++)
{
if(mat[i][k])
{
for(int j=1;j<=2;j++)
res.mat[i][j]=(res.mat[i][j]+mat[i][k]*mt.mat[k][j]%mod)%mod;
}
}
}
return res;
}
};
matrix mpower(matrix m,ll b)
{
matrix res;
res.zero();
res.eye();
while(b)
{
if(b&1) res=res*m;
m=m*m;
b>>=1;
}
return res;
}
void init(matrix &a)
{
a.zero();
a.mat[1][1]=1;
}
void init2(matrix &a)
{
a.zero();
a.mat[1][1]=3;
a.mat[1][2]=1;
a.mat[2][1]=2;
}
int main()
{
ll a,ans=0,q,n;
scanf("%lld%lld",&q,&n);
matrix A,B,t;
init(A);
init2(B);
while(q--)
{
if(mp.count(n))
a=mp[n];
else
t=A*mpower(B,n-1);
a=t.mat[1][1];
mp[n]=a;
n=n^(a*a);
ans=ans^a;
}
printf("%lld\n",ans);
return 0;
}
(2)可以求出循环节求解
(3)斐波那契数列的通项公式:
\(\sqrt{17}\) 在模 \(p\) 意义下等价于 \(17\) 模 \(p\) 的二次剩余,本题中这个值存在且是一个整数;但依然会多一个快速幂的 \(log\),这里 \(n\) 可以用欧拉降幂降到 \(2e9\) 以内。
设 \(N=\sqrt{2e9}\) ,\(n=k*N+r\),有 \(x^n=x^{k*N}*x^r\),注意到 \(k\leq N,r\leq N\),预处理出最后的两部分就可以 \(O(1)\) 查询出 \(F(n)\)。
标签:map inline 斐波那契数列 res order using while 数列 include
原文地址:https://www.cnblogs.com/1024-xzx/p/13252206.html