AT_abc283_g [ABC283G] Partial Xor Enumeration 题解
前置知识
解法
考虑线性基。
因为有可空子序列也参与运算,所以第 \(1\) 小的数是 \(0\);但线性基中是不允许有异或和为 \(0\) 的存在,故线性空间内第 \(k-1\) 小的数就是所求的第 \(k\) 小的数。
令每一个二进制位仅在它这一位的基底上出现,其他位上的基底直接异或掉。
将 \(k\) 二进制分组后取每一位的基底异或起来即可。
观察到 \(r-l \le 2 \times 10^{5}\),暴力处理每一组询问即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
ll d[70];
vector<ll>dd;
void insert(ll x)
{
for(ll i=60;i>=0;i--)
{
if((x>>i)&1)
{
if(d[i]==0)
{
d[i]=x;
break;
}
x^=d[i];
}
}
}
ll ask(ll x)
{
x--;
ll ans=0;
for(ll i=0;i<dd.size();i++)
{
if((x>>i)&1)
{
ans^=dd[i];
}
}
return ans;
}
int main()
{
ll n,l,r,x,i,j;
cin>>n>>l>>r;
for(i=1;i<=n;i++)
{
cin>>x;
insert(x);
}
for(i=0;i<=60;i++)
{
if(d[i]!=0)
{
for(j=0;j<=i-1;j++)
{
if((d[i]>>j)&1)
{
d[i]^=d[j];
}
}
dd.push_back(d[i]);
}
}
for(i=l;i<=r;i++)
{
cout<<ask(i)<<" ";
}
return 0;
}
后记
多倍经验: HDU3949 XOR
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18456549,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。