【十二省2019】异或粽子

题面

https://www.luogu.org/problem/P5283

题解

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define N 500050
#define ri register int
#define din(a,b) ((a&(1LL<<b))==(1LL<<b))
using namespace std;

struct node{
  int cnt;
  int ch[2];
} trie[N*40*3];

int n,k,clo,root[N];
unsigned int a[N],x;

struct HeapNode {
  unsigned int c;
  int r;
  bool operator < (const HeapNode &rhs) const {
    return (c^a[r])<(rhs.c^a[rhs.r]);
  }
};
priority_queue<HeapNode> q;

void build(unsigned int x,int now){
  trie[now].cnt++;
  for (ri i=31;i>=0;i--) {
    if (din(x,i)) trie[now].ch[1]=++clo,now=clo;
      else trie[now].ch[0]=++clo,now=clo;
    trie[now].cnt++;
  }
}

void insert(unsigned int x,int pre,int &now) {
  now=++clo;
  int no=now; trie[no]=trie[pre]; trie[no].cnt++;
  for (ri i=31;i>=0;i--) {
    if (din(x,i)) trie[no].ch[1]=++clo,pre=trie[pre].ch[1],no=clo;
      else trie[no].ch[0]=++clo,pre=trie[pre].ch[0],no=clo;
    if (pre) trie[no]=trie[pre];
    trie[no].cnt++;
  }
}

unsigned int search(unsigned int x,int pre,int &now) {
  unsigned int ret=0;
  now=++clo;
  int no=now; trie[no]=trie[pre]; trie[no].cnt--;
  for (ri i=31;i>=0;i--) {
    if (din(x,i)) {
      if (trie[no].ch[0] && trie[trie[no].ch[0]].cnt) {
        trie[no].ch[0]=++clo;
        no=clo;
        pre=trie[pre].ch[0];
      }
      else {
        trie[no].ch[1]=++clo;
        no=clo;
        pre=trie[pre].ch[1];
        ret+=(1LL<<i);
      }
    }
    else {
      if (trie[trie[no].ch[1]].cnt) {
        trie[no].ch[1]=++clo;
        no=clo;
        pre=trie[pre].ch[1];
        ret+=(1LL<<i);
      }
      else {
        trie[no].ch[0]=++clo;
        no=clo;
        pre=trie[pre].ch[0];
      }
    }
    trie[no]=trie[pre];
    trie[no].cnt--;
  }
  return ret;
}

int main() {
  //freopen("1.in","r",stdin);
  //freopen("1.out","w",stdout);
  scanf("%d %d",&n,&k);
  for (ri i=1;i<=n;i++) {
    scanf("%u",&x);
    a[i]=a[i-1]^x;
  }
  root[1]=1; clo=1;
  build(0LL,root[1]);
  for (ri i=1;i<=n;i++) {
    insert(a[i],root[i],root[i+1]);
    //puts("102"); puts("");
    //dfs(root[i+1]);
    //puts("");
  }
  for (ri i=1;i<=n;i++) {
    //puts("104");dfs(root[i]); puts(""); puts("");
    unsigned int t=search(a[i],root[i],root[i]);
    q.push((HeapNode){t,(int)i});
    //puts("107");dfs(root[i]); 
  }
  long long sum=0;
  for (ri i=1;i<=k;i++) {
    HeapNode cur=q.top(); q.pop();
    sum+=cur.c^a[cur.r];
    if (trie[root[cur.r]].cnt) {
      unsigned int t=search(a[cur.r],root[cur.r],root[cur.r]);
      q.push((HeapNode){t,cur.r});
    }
  }
  printf("%lld\n",sum);
}

猜你喜欢

转载自www.cnblogs.com/shxnb666/p/11279426.html