题解:P8019 [ONTAK2015] OR-XOR

· · 题解

题意概述

题目清晰明了不做赘述。

思路分析

涉及区间的异或和,我们考虑维护前缀异或和。要总费用尽可能的小,就贪心的让分的每一段的高位尽可能为零,那就要考虑把每一位拆开进行处理。

Solution

从高位到地位枚举。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int n,m,a[N],maxv,s,ans;
bool vis[N];

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        maxv=max(maxv,a[i]);
        a[i]^=a[i-1];
    }
    for(;maxv;s++) maxv>>=1;
    for(int i=s-1;i>=0;i--)
    {
        int d=0;
        for(int j=1;j<=n;j++) d+=(!((a[j]>>i)&1)&&!vis[j]);//这个数的这一位为零且能作为之前高位的隔断才有效
        if(d<m||(a[n]>>i)&1)
        {
            ans+=1ll<<i;
            continue;
        }
        for(int j=1;j<=n;j++) vis[j]=((a[j]>>i)&1||vis[j]);//如果这一位为一那么就不能作为隔断
    }
    cout<<ans;
    return 0;
}