当前位置:网站首页>Linear basis count (k large XOR sum)

Linear basis count (k large XOR sum)

2022-06-26 13:58:00 __ LazyCat__

Linear basis counting (k Great difference or and )

link :#114. k Great difference or and - subject - LibreOJ (loj.ac)

The question : Given a reproducible set S, Ask many times for the first k Small true subsets XOR and .

Answer key : Reconstruct the linear basis , send p [ i ] p[i] p[i] Of the j Bit in p [ j ] p[j] p[j] In case of existence, it is not 1, So XOR p [ j ] p[j] p[j] It must make the value larger , Abstracting into binary is to take p [ j ] p[j] p[j] amount to j Position fetching 1, Then you can put k Check the XOR result by bit .

tips: When the number of linear bases c n t cnt cnt Less than n when , Explain the non full rank , All results can be XOR 0, So it seems that the 1 As small as 0 Instead of p [ 0 ] p[0] p[0], So for k Minus one . The total XOR result is no more than 2 c n t − 1 2^{cnt}-1 2cnt1 Of .

//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>

using namespace std;
typedef long long ll;
const int maxn=55;

ll p[maxn],f[maxn],cnt,n,m,ans,u,v,w;

inline void insert(ll x)
{
    
	for(int i=50;i>=0;i--)
	{
    
		if(x>>i&1)
		{
    
			if(!p[i]){
    p[i]=x; break;}
			x^=p[i];
		}
	}
	return;
}

inline void rebuild()
{
    
	for(int i=0;i<=50;i++)
	{
    
		for(int j=i-1;j>=0;j--)
		{
    
			if(p[i]>>j&1)p[i]^=p[j];
		}
		if(p[i])f[cnt++]=p[i];
	}
	return;
}

inline ll query(ll k)
{
    
	if(cnt!=n)k--;
	if(k>=(1ll<<cnt))return -1;
	ll ans=0;
	for(int i=0;i<cnt;i++)ans^=f[i]*(k>>i&1);
	return ans;
}

int main()
{
    
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
		cin>>u,insert(u);
	}
	rebuild(),cin>>m;
	for(int i=1;i<=m;i++)
	{
    
		ll k; cin>>k,cout<<query(k)<<"\n";
	} 
	return 0;
}
原网站

版权声明
本文为[__ LazyCat__]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202170511166897.html