1. 程式人生 > 其它 >E. Bored Bakry

E. Bored Bakry

E. Bored Bakry

題意:給定一個長度為 n 的序列 an ,找出最長的 good 子序列的長度。當一個序列 al-r 滿足它的 & 大於它的 ^ 時,我們稱該序列是 good 序列。

分析:來分析一個 good 序列性質。

  • 不妨設一個序列的 & 為 X ,一個序列的 ^ 為 Y 。
  • X > Y 即存在 i 使得在大於 i 的位上 X 與 Y 相等,在第 i 位上 X 大於 Y 。也就是說 Xi 為 1 ,Yi 為 0 。
  • 進一步可以發現這個序列一定是偶數長度的。這說明:對於某一比 i 高的 j 位,Xj = Yj = 0 ,因為Xj = Yj = 1 是不可能的。
  • 具體操作時,我們列舉每一個二進位制位 i 。如果一個序列 al-r 的第 i 位全部為 1 ,且對於任意 j≥ i ,j 位上的異或和都為 0 ,則該序列是 good 序列。
  • 現在有一個問題我們沒有保證 Xj 也必須為 0 。其實這已經沒有必要了,因為主要的要求 X > Y 已經被滿足了。
#include<bits/stdc++.h>
#define ll long long
#define ls u<<1
#define rs u<<1|1
#define mm(x) memset(x,0,sizeof(x))
#define debug(x) cout << #x << ":" << x << '\n'
using
namespace std; int read() { int a=0;int f=0;char p=getchar(); while(!isdigit(p)){f|=p=='-';p=getchar();} while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=getchar();} return f?-a:a; } const int INF=998244353; int T; int n; int ans; int val[1000050]; int vval[1000050]; int sum[1000050]; bool vis[1000050
]; int tmp[2000050]; int tim[2][2000050]; queue<int >q; void init() { while(!q.empty()) { int u=q.front(); q.pop(); tmp[sum[u-1]]=INF; } } int main() { n=read(); ans=0; for(int i=1;i<=n;++i) val[i]=read(); memset(tmp,127,sizeof(tmp)); for(int k=1<<20;k>=1;k>>=1) { for(int i=1;i<=n;++i) { vval[i]^=(val[i]&k); if(val[i]&k) vis[i]=1; else vis[i]=0; } for(int i=1;i<=n;++i) sum[i]=sum[i-1]^vval[i]; init(); for(int i=1;i<=n;++i) if(!vis[i]) { init(); } else { q.push(i); tmp[sum[i-1]]=min(tmp[sum[i-1]],i-1); ans=max(ans,i-tmp[sum[i]]); } } printf("%d",ans); return 0; }
View Code