浣熊的小游戏 题解
官方题解已经过审:https://www.luogu.com.cn/article/8rkkw6gb。
申明:本题解作者为本题出题人【数据删除】,因不能挂名,已经过原作者同意,由我代发。
我们使用人类智慧将题意进行转换,发现原题等价于使用值域内相邻两数的异或和能异或出多少种值。
简要证明如下:
首先,我们选择很多对相邻两个数异或,得到的一定是偶数个数异或的结果,因为每次新加进来了一对相邻数的异或,这对数里若有
然后,所有偶数个数异或,都一定可以通过相邻两数异或出来。我们将这偶数个数从左至右两两配对,对于每一对数
可这有什么用呢?我们会发现相邻两数异或起来得到的值十分特殊,容易发现在二进制下对一个数加
又因为
再考虑这些数异或起来有多少种结果,当然你可以写线性基,直觉一下不难发现其结果就是
做到这里可以拿
接下来,考虑快速找到范围内相邻两数异或值种类数。容易发现如果存在相邻两数异或值为
我们枚举
注意到该判断与求一个区间内
总的时间复杂度
PS:注意到
CODE
#include<bits/stdc++.h>
using namespace std;
long long q,l,r,ans,i;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>q;
while(q--){
cin>>l>>r;
ans=0;
for(i=0;i<=60;i++)
if(((r>>i)-(l>>i))!=((r>>i+1)-(l>>i+1)))
ans++;
cout<<(((long long)1<<ans)-1)<<"\n";
}
}