【做题记录】位运算

CF1592E Bored Bakry

题意:找出最长的区间 ([l,r]) 满足 (a_{l}&a_{l+1}&dots&a_{r-1}&a_{r}>a_{l}oplus a_{l+1}oplusdotsoplus a_{r-1}oplus a_{r})

首先发现如果有一段满足这个条件的区间,那么一定有一个(较高的)二进制满足:这个区间中的所有数的这一位都是 (1) 且数量为偶数。

又考虑到如果有更高位满足了这个条件,低位都不用再考虑了。

但是如果在这一位满足条件时,存在更高位的 (&)(oplus) 小怎么办?

那么考虑强制规定更高为的异或和为 (0) ,可以证明在枚举到更高位时情况没有算漏。

因此枚举满足条件的二进制位,找出一段极长的区间满足这一段区间中忽略比这一位第的二进制位后异或之和为 (0)

$ exttt{code}$
n=rd();
for(int i=1;i<=n;i++) a[i]=rd();
memset(exist,-1,sizeof(exist));
for(int p=0;p<=20;p++)
{
	 tot0[cnt=1]=0;
	 for(int i=1;i<=n;i++) if(!((a[i]>>p) & 1)) tot0[++cnt]=i;
	 tot0[++cnt]=n+1;
	 for(int i=2,l,r;i<=cnt;i++)
	 {
	 	 l=tot0[i-1]+1,r=tot0[i]-1;
	 	 for(int j=l;j<=r;j++) xorsum[j]=xorsum[j-1]^(a[j]>>p);
	 	 exist[0]=l-1;
	 	 for(int j=l;j<=r;j++)
	 	 {
	 	 	 if(exist[xorsum[j]]!=-1) ans=max(ans,j-exist[xorsum[j]]);
	 	 	 else exist[xorsum[j]]=j;
		 }
		 exist[0]=0;
	 	 for(int j=l;j<=r;j++) exist[xorsum[j]]=-1,xorsum[j]=0;
	 }
}
printf("%d
",ans);
原文地址:https://www.cnblogs.com/EricQian/p/15366917.html