Description
多组询问,对于每组,要求回答用l~r中的数,可以异或出多少个不同的数。
Solution
这题用线性基
首先可以把l强制加入线性基中,
那么,接下来加入的数一定要大于l,于是就从小到大加入线性基中,
从二进制的低位往高位找,找到一个0就把它变成1,把这位以后的变成0,也就是模拟进位,当然,找到的这位在线性基中要是空的,
找到了,就把它加入到这一位的线性基中,答案*2,
复杂度: O(Tlog(l)2)
Code
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long LL;
const int N=65;
LL er[N];
int a[N];
LL l,r,ans;
int main()
{
int _;
er[1]=1;fo(i,2,62)er[i]=er[i-1]<<1;
for(scanf("%d",&_);_;_--)
{
scanf("%lld%lld",&l,&r);
if(l==r&&!l){printf("1\n");continue;}
fo(i,1,61)a[i]=0;
fod(i,61,1)if(l&er[i]){a[i]=1;break;}
ans=1;
if(l)ans=2;
for(LL q=l;q<=r;)
{
int t=65;
fo(i,1,61)if(!a[i]&&!(er[i]&q)){t=i;break;}
if(t>61)break;
q+=er[t];a[t]=1;
if(t>1)q=q&(er[62]-er[t]);
if(q<=r)ans*=2LL;
}
printf("%lld\n",ans);
}
return 0;
}