【十二省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); }