• 【十二省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
    ",sum);
    }
  • 相关阅读:
    鼠标移向小图显示大图
    一个简单漂亮的CSS相册代码
    windows 应该关闭服务
    NetBIOS名称
    DOS命令大全(经典收藏)
    大揭露:Win中也有各种不老实的服务
    变量名
    ASP.NET2.0 GridView小技巧汇粹 (转)
    Dfs实战技术
    windows 2003中活动目录支持文件
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279426.html
Copyright © 2020-2023  润新知