NOI.AC省选赛 第五场T1
A. Mas的童年
题目链接
思路
0x00
\(n^2\)的暴力挺简单的。
ans=max(ans,xor[j-1]+xor[j-1]^xor[i]);
01trie树求最大异或和相信大家都会。不会看.
这与我们今天这个题目有关吗? 毫无关系。 xor[i]的某一位为1,xor[j]的那一位不管是啥,贡献都是为1。 而xor[i]的某一位为0,xor[j]的贡献是2或0。(xor[j]位上为1贡献为2) (这里的1,2都是2^(k)的1倍,两倍) 所以我们只要考虑xor[i]的位上为0的贡献。 将xor[i]取反,就是求与(&)最大值。 最后整理一下就可以计算出答案了。0x01
如何求与(&)最大值
把每个插入的值的所有子集装进一个桶里。 然后从大到小选择判断是否在桶里面出现过,因为从大到小枚举,所以一定不会冲突掉,就好了,这看代码比较清晰。 相似的,我们也可以求或(|)的最大值0x02
复杂度?
x如果枚举过了就不用再枚举 那复杂度就是每个数枚举下二进制\((nlogn)\) 当然如果插入数的上限太大了话应该就做不了。代码
#includeusing namespace std;const int N=2e6+7;int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f;}int n,a[N],xo[N],tong[N];void mark(int x) {//枚举子集 tong[x]=1; for(int i=0;i<20;i++) if((x>>i&1)&&(!tong[x^(1< =0;--i) if(!((1<