CF1592E Bored Bakry

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1592E Bored Bakry相关的知识,希望对你有一定的参考价值。

CF1592E Bored Bakry

题意:

给你长度为n的数组a,现在定义一段区间[l,r]为good,如果 a l & a l + 1 & . . . & a r > a l ⊕ a l + 1 ⊕ . . . ⊕ a r a_{l}\\& a_{l+1}\\&...\\&a_{r}>a_{l}⊕a_{l+1}⊕...⊕a_{r} al&al+1&...&ar>alal+1...ar
请输出good区间的最长长度

题解:

我们先去考虑&与⊕的区别,满足情况的区间一定是偶数长度,如果是奇数长度,左侧全是1(二进制),右侧全是1,两侧结果都还是1,不满足>。只有区间长度为偶数,左侧二进制第k位全是1,右侧也全是1,这样才行。
我们从最高位开始枚举这个k,good区间要满足,存在一个二进制某一位k,某个长度为偶数的序列每个数在这一位上都是1,并且二进制位大于等于k的数的异或和应该是0(因为等于k的全是1,偶数个,异或为0,而大于k的异或值都要为0才不会对第k位的情况造成干扰)

那么我们就需要对于每个k下的区间进行判断,用到两个数组:数组b表示第k位上前i个数里有多少个数这一位是1,数组c表示前i个数在高于b的位置上的异或和
如果数组c中出现两个一样的数,说明这两个数之间的数异或和为0,如果这一段都是1(用b数组的前缀和之差是否等于区间长度来判断),说明这个区间正好满足定义,用这个长度更新ans就可以了
详细看代码

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);
}
template <typename T> inline void write(T x)
{
    if (x < 0) {
        x= ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#else
    startTime = clock ();
    freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn=1e6+9;
int a[maxn];
int b[maxn];
int sum[maxn]; 
int vis[maxn];
int main()
{
    //rd_test();
    int n;
	read(n);
	int ans=0;
	for(int i=1;i<=n;i++)read(a[i]);
	for(int j=20;j>=0;j--){
		for(int i=1;i<=n;i++){
			b[i]=b[i-1]+((a[i]>>j)&1);
			sum[i]=sum[i-1]^(a[i]>>j);
		}
		memset(vis,-1,sizeof(vis));
		vis[0]=0;
		for(int i=1;i<=n;i++){
			if(vis[sum[i]]!=-1){
				if(b[i]-b[vis[sum[i]]]==i-vis[sum[i]])
				{
					ans=max(ans,i-vis[sum[i]]);
//					printf("%d %d\\n",vis[sum[i]],i);
				}
				else vis[sum[i]]=i;
			}
			else {
				vis[sum[i]]=i;
			}
		}
	}
	cout<<ans<<endl;
    //Time_test();
}



以上是关于CF1592E Bored Bakry的主要内容,如果未能解决你的问题,请参考以下文章

Gym 101102C Bored Judge(set--结构体集合)

Codeforces Round #746 (Div. 2) C. Bakry and Partitioning

Round #422 A. I'm bored with life

A - I'm bored with life

如何从后台弹出片段

Codeforces Round #422 (Div. 2) A. I'm bored with life 暴力