CF1592E Bored Bakry
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>al⊕al+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