CF959F Mahmoud and Ehab and yet another xor task 题解
前置知识
解法
将操作离线下来,并按 \(\{ l \}\) 升序排序,接着顺序插入线性基并处理询问。
对于未成功插入线性基的元素 \(k\) 一定能被线性基内选出若干元素得到。故在 \(x\) 能被表出的情况下,设 \(1 \sim l\) 中成功插入线性基的元素个数为 \(siz\),对于剩下 \(l-siz\) 个元素选出若干个总方案数为 \(2^{l-siz}\),这 \(2^{l-siz}\) 种方案都存在一种在线性基中选出若干个元素使得异或起来等于 \(x\)。
故 \(2^{l-siz}\) 即为所求。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
const ll p=1000000007;
struct node
{
ll l,x,id;
}q[100010];
ll a[100010],d[30],ans[100010];
bool cmp(node a,node b)
{
return a.l<b.l;
}
ll insert(ll x)
{
for(ll i=20;i>=0;i--)
{
if((x>>i)&1)
{
if(d[i]==0)
{
d[i]=x;
return 1;
}
x^=d[i];
}
}
return 0;
}
bool check(ll x)
{
for(ll i=20;i>=0;i--)
{
if((x>>i)&1)
{
if(d[i]==0)
{
return 0;
}
x^=d[i];
}
}
return 1;
}
ll qpow(ll a,ll b,ll p)
{
ll ans=1;
while(b)
{
if(b&1)
{
ans=ans*a%p;
}
b>>=1;
a=a*a%p;
}
return ans;
}
int main()
{
ll n,m,siz=0,i,j;
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
for(i=1;i<=m;i++)
{
cin>>q[i].l>>q[i].x;
q[i].id=i;
}
sort(q+1,q+1+m,cmp);
for(i=1,j=1;i<=m;i++)
{
while(j<=q[i].l)
{
siz+=insert(a[j]);
j++;
}
ans[q[i].id]=(check(q[i].x))*qpow(2,q[i].l-siz,p);
}
for(i=1;i<=m;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18456734,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。