[十二省联考]异或粽子

复杂度分析错了不敢写也就我了吧

大概是在考场上把细节都想到了233

k*2然后最后答案/2就不用可持久化了

//Love and Freedom.
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#define pa pair<ll,int>
#define mp make_pair 
#define ll long long
#define inf 20021225
#define N 500010
#define fs first
#define se second
using namespace std;

priority_queue<pa> que; int pos[N],rt[N],n,k,tot[N]; bool fin[N];
struct node{int son[2],sz,fa;ll val;}t[N*32]; ll a[N]; int poi;
void insert(ll s)
{
    int x=0;
    for(int i=32;~i;i--)
    {
        if(!t[x].son[(s>>i)&1])    t[x].son[(s>>i)&1]=++poi,t[poi].fa=x;
        t[x].sz++; x=t[x].son[(s>>i)&1];
    }
    t[x].sz++; t[x].val=s;// printf("*%d ",x);
}
ll query(int x)
{
    if(fin[x])    return 0;
    if(tot[x]<t[pos[x]].sz)
        return tot[x]++,t[pos[x]].val^a[x];
    int i=0,px=pos[x]; ll val=t[px].val; tot[x]=0;
    while(i<=32)
    {
        int vv=(val>>i)&1,av=(a[x]>>i)&1;
        if(vv^av&&t[t[px].fa].son[av]){px=t[t[px].fa].son[av]; break;}
        else    px=t[px].fa; i++;
    }
    if(i>32)    return fin[x]=1,0;
    for(i=i-1;~i;i--)
    {
        if(t[px].son[((a[x]>>i)&1)^1])    px=t[px].son[((a[x]>>i)&1)^1];
        else     px=t[px].son[(a[x]>>i)&1];
    }
    tot[x]=1; pos[x]=px; return t[px].val^a[x];
}
ll prework(int x)
{
    int px=0;
    for(int i=32;~i;i--)    if(t[px].son[((a[x]>>i)&1)^1])
        px=t[px].son[((a[x]>>i)&1)^1];
        else     px=t[px].son[(a[x]>>i)&1];
    tot[x]=1; pos[x]=px; return t[px].val^a[x];
}
int main()
{
    scanf("%d%d",&n,&k); k<<=1; insert(0);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]); a[i]^=a[i-1]; insert(a[i]);
    }
    que.push(mp(prework(0),0));
    for(int i=1;i<=n;i++)    que.push(mp(prework(i),i)); ll ans=0;
    for(int i=1;i<=k;i++)
    {
        pa tmp=que.top(); ans+=tmp.fs; que.pop();
        que.push(mp(query(tmp.se),tmp.se));
    }
    printf("%lld\n",ans>>1);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/hanyuweining/p/10801728.html