RT,已经运用题解方法,但随brtcnt取值分数在20-60之间变化:
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define brtcnt 64
ull sd = 111111111111111111ull, sd2, k = 1, brt;
ull qu, n, ans, kkk, len;//qu表示每次询问的位置。
inline ull get_q(int i)
{
sd = (sd2 ^ (sd2 >> 3)) + 998244353;
return ((sd2 = sd ^ (sd << 37)) & k) + ((i & 1) ? 0 : (n - k - 1));
}
int q, q2;
void init()
{
kkk=log(n)/log(2);
ull nn=n,aa[101],tot=0;
if(nn%2==1)
{
len=n;
return;
}
while(nn)
{
aa[++tot]=nn%2;
nn/=2;
}
for(register int i=1;i<=tot;i++)if(aa[i]==0)len++;
len=n/(1<<len);
}
inline ull get_ans(ull x)
{
if(n==1)return kkk;
else
{
x=x-len*(unsigned long long)(brt*x>>brtcnt);
while(x>=len)x-=len;
if(x>len/2)x=len-x-1;
if(x>(1<<n)-2)return kkk;
else if(x&1)return kkk+1;
else return kkk;
}
}
int main()
{
cin >> n;
sd2 = n;
while((k << 1) <= n + 1) k <<= 1;
k -= 1;
cin >> q >> q2;
init();
brt=((__uint128_t)1<<brtcnt)/len;//brt初始化
// cout<<len<<endl;
for(int i = 1; i <= q; i++)
{
cin >> qu;
// cout<<qu<<" "<<get_ans(qu)<<endl;
ans += get_ans(qu) * i;
}
for(int i = 1; i <= q2; i++)
{
qu = get_q(i);
ans += get_ans(qu) * (i + q);
}
cout << ans << endl;
return 0;
}