版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
正题
我这辈子都不会忘了特征根的。
发现式子很难看,怎么带了一个考虑把它消掉:
那么下减上就可以消掉了,变成:
根据高阶递推式的特征方程我们可以知道:
四个根就很显然了,发现有两个重根:
那么我们只要把A,B,C,D解出来就可以了。
然后用光速幂和欧拉定理就可以做到小常数的了!
#include<bits/stdc++.h>
using namespace std;
const int block=1<<16;
long long A[block],B[block],d=281250002;
int T;
const long long mod=1e9+7;
void prepare(){
A[0]=1;A[1]=3;for(int i=2;i<block;i++) A[i]=A[i-1]*A[1]%mod;
B[0]=1;B[1]=A[block-1]*A[1]%mod;for(int i=2;i<block;i++) B[i]=B[i-1]*B[1]%mod;
}
namespace Mker
{
// Powered By Kawashiro_Nitori
// Made In Gensokyo, Nihon
#include<climits>
#define ull unsigned long long
#define uint unsigned int
ull sd;int op;
inline void init() {scanf("%llu %d", &sd, &op);}
inline ull ull_rand()
{
sd ^= sd << 43;
sd ^= sd >> 29;
sd ^= sd << 34;
return sd;
}
inline ull rand()
{
if (op == 0) return ull_rand() % USHRT_MAX + 1;
if (op == 1) return ull_rand() % UINT_MAX + 1;
if (op == 2) return ull_rand();
}
}
long long Mi3(unsigned long long n){
return A[n%block]*B[n/block]%mod;
}
int main(){
scanf("%d",&T);
Mker::init();
prepare();
long long last=0;
while(T--){
unsigned long long n=Mker::rand();
long long ans=36,tmp=Mi3((n+2)%(mod-1))*(4*(n%mod)-13+mod)%mod;
n&1?ans+=15:ans-=15;
ans=(ans+tmp)*d%mod;
last^=ans;
}
printf("%lld\n",last);
}