題意:q次查詢,輸出所有的查詢異或的結果
每次查詢是的第n項,查詢的n是上一次的結果的平方異或上一次的n
題解:首先要發現查詢fn的循環節是mod-1,然後這樣還不夠因爲查詢次數太多了時間還是不行
這時可以把取模數取小一點(例如100,或者1000),會發現q次查詢ans在過程中會來回震盪,即兩個數來回變
這時候就要跳出循環了
然後別忘了,因爲發現循環節是mod-1,在算快速冪的時候別忘了模mod-1
最後,數組不要開太大,開內存會佔很多時間
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1e6+5;
const int mod = 998244353;
struct Mat
{
ll m[3][3];
};//存儲結構體
Mat a,e; //a是輸入的矩陣,e是輸出的矩陣
Mat Mul(Mat x,Mat y)
{
Mat c;
memset(c.m,0,sizeof(c.m));
for(int i=1;i<=2;++i){
for(int j=1;j<=2;++j){
for(int k=1;k<=2;++k){
c.m[i][j] = (c.m[i][j] + x.m[i][k]*y.m[k][j])%mod;
}
}
}
return c;
}
inline Mat pow(Mat x,ll y)//矩陣快速冪
{
y%=998244352;
Mat ans = e;
if(y==0)return ans.m[2][1]=0,ans;
if(y==1)return ans.m[2][1]=1,ans;
if(y==2)return ans.m[2][1]=3,ans;
while(y){
if(y&1) ans = Mul(ans,x);
x = Mul(x,x);
y>>=1;
}
return ans;
}
void init(){
e.m[1][1]=1;e.m[1][2]=0;
e.m[2][1]=0;e.m[2][2]=1;
a.m[1][1]=3;a.m[1][2]=2;
a.m[2][1]=1;a.m[2][2]=0;
}
int main()
{
// #ifndef ONLINE_JUDGE //if not define 如果沒有定義這個的話就執行下面
// freopen("input.in", "r", stdin); //只改變輸入流的文件指針,讀入這個文件的內容(必須要有input這個文件)stdin是標準輸入流的文件指針
// freopen("output1.out", "w", stdout); //只改變輸出流的文件指針,寫入output內(如果沒有output這個文件就會自動生成)stdout是標準輸出流的文件指針
// #endif
ll q,n,ans=0;
cin>>q>>n;
ll ln=-1,lans=-1,lln=-1;
for(int i=1;i<=q;i++){
init();
Mat f=pow(a,n);
ll tmp=f.m[2][1];
lln=ln;ln=n;lans=ans;
n=n^(1ll*tmp*tmp);
ans^=tmp;
if(n==lln){
if((q-i+1)&1){printf("%lld\n",ans);return 0;}
else {printf("%lld\n",lans);return 0;}
}
}
cout<<ans<<endl;
return 0;
}