利用前缀和选m个区间等价于选m个数
从最高位开始找,如果这一位至少有m个0,则可以为0,该位为1的后面就不可以选了。
还要注意,最后一个数如果该位为1,那么这一位必须为1,然后要从62开始枚举,而不是从31
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; #define N 500010 int n,m; int cnt; LL ans; LL a[N]; bool v[N]; int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]^=a[i-1]; for (int i=62;i>=0;i--) { cnt=0; for (int j=1;j<=n;j++) if (!v[j] && !(a[j]&(1LL<<(LL)i))) ++cnt; if (cnt<m || (a[n] & (1LL<<(LL)i))) ans+=(1LL<<(LL)i); else for (int j=1;j<=n;j++) if (!v[j] && (a[j] & (1LL<<(LL)i))) v[j]=1; } printf("%lld",ans); return 0; }
时间: 2024-10-13 02:19:06