• 【十二省联考2019】异或粽子/可持久化01trie


    可持久化01trie支持查询最大的区间异或和。

    对于普通01trie,我们每次新建的是一条新边(也有可能不建)

    而可持久化01trie就像主席树一样,每次利用历史版本新建。

    一般学到可持久化01trie的都学过主席树了吧,所以我就不讲思想了

     1 struct tree{
     2     LL ch[2],id,cnt;
     3 }tr[N*50];
     4 LL tot=0;
     5 
     6 void Insert(LL co,LL &now,LL k,LL pos,LL bit){
     7     // 历史版本,新建的树,数值,原序列中的位置,当前高度 
     8     tr[now=++tot]=tr[co];//新建节点 
     9     ++tr[now].cnt;//++次数 
    10     if(bit<0){tr[now].id=pos;return;}
    11     bool c=k&(1LL<<bit);//一定要用bool,RE的血泪史。 
    12     Insert(tr[co].ch[c],tr[now].ch[c],k,pos,bit-1);
    13     return;
    14 }
    15 
    16 inline LL query(LL l,LL r,LL k,LL bit){
    17     //     左边界,右边界,数值,高度 
    18     if(bit<0)return tr[r].id;
    19     bool c=k&(1<<bit);
    20     LL rem=tr[tr[r].ch[c^1]].cnt-tr[tr[l].ch[c^1]].cnt;
    21     if(rem)return query(tr[l].ch[c^1],tr[r].ch[c^1],k,bit-1);
    22     else return query(tr[l].ch[c],tr[r].ch[c],k,bit-1);
    23     //贪心的选取c^1,实在没得选也就只能走c了 
    24 }

    例题:异或粽子

    对于一个起点 i ,找到它与 sum[ (i,n] ] 异或的最大位置,记为pos。

    开一个结构体

    1 struct D{
    2     LL st;
    3     LL l,r,pos;//pos可选的区间
    4     LL sum;//这个可以不用存
    5     bool operator < (D b) const{
    6         return sum<b.sum;
    7     }
    8 };

    压到大根堆里,每次取出最大的,然后把 [ l , r ] 从pos那里分成两个区间,分别算出pos再压进去。

    重复k次。

    代码写的很仓促,某谷会TLE两个点,仅供参考。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<queue>
     6 #include<cctype>
     7 using namespace std;
     8 #define LL long long
     9 const int N=500005;
    10 LL n,x,k;
    11 LL sum[N];
    12 struct tree{
    13     LL ch[2],id,cnt;
    14 }tr[N*50];
    15 LL rt[N];
    16 LL tot=0;
    17 void Insert(LL co,LL &now,LL k,LL pos,LL bit){
    18     // 历史版本,新建的树,数值,原序列中的位置,当前高度 
    19     tr[now=++tot]=tr[co];//新建节点 
    20     ++tr[now].cnt;//++次数 
    21     if(bit<0){tr[now].id=pos;return;}
    22     bool c=k&(1LL<<bit);//一定要用bool,RE的血泪史。 
    23     Insert(tr[co].ch[c],tr[now].ch[c],k,pos,bit-1);
    24     return;
    25 }
    26 
    27 inline LL query(LL l,LL r,LL k,LL bit){
    28     //     左边界,右边界,数值,高度 
    29     if(bit<0)return tr[r].id;
    30     bool c=k&(1<<bit);
    31     LL rem=tr[tr[r].ch[c^1]].cnt-tr[tr[l].ch[c^1]].cnt;
    32     if(rem)return query(tr[l].ch[c^1],tr[r].ch[c^1],k,bit-1);
    33     else return query(tr[l].ch[c],tr[r].ch[c],k,bit-1);
    34     //贪心的选取c^1,实在没得选也就只能走c了 
    35 }
    36 
    37 struct D{
    38     LL st;
    39     LL l,r,pos;
    40     LL sum;
    41     bool operator < (D b) const{
    42         return sum<b.sum;
    43     }
    44 };
    45 
    46 priority_queue<D> q;
    47 
    48 LL ans=0;
    49 
    50 int main(){
    51     //freopen("1.in","r",stdin);
    52     scanf("%lld%lld",&n,&k);
    53     for(LL i=1;i<=n;++i){
    54         scanf("%lld",&x);
    55         sum[i]=sum[i-1]^x;
    56     }
    57     for(LL i=1;i<=n;++i){
    58         Insert(rt[i-1],rt[i],sum[i],i,33);
    59     }
    60     for(LL i=1;i<=n;++i){
    61         LL l=i;
    62         LL r=query(rt[l-1],rt[n],sum[l-1],33);
    63         q.push((D){l,l,n,r,sum[r]^sum[l-1]});
    64     }
    65     while(k--){
    66         D tmp=q.top();q.pop();
    67         ans+=tmp.sum;
    68         LL st=tmp.st;
    69         LL i=tmp.l,j=tmp.r;
    70         if(i<tmp.pos){
    71             LL t=query(rt[i-1],rt[tmp.pos-1],sum[st-1],33);
    72             q.push((D){st,i,tmp.pos-1,t,sum[t]^sum[st-1]});
    73         }
    74         if(j>tmp.pos){
    75             LL t=query(rt[tmp.pos],rt[j],sum[st-1],33);
    76             q.push((D){st,tmp.pos+1,j,t,sum[st-1]^sum[t]});
    77         }
    78     }
    79     cout<<ans;
    80     return 0;
    81 }
  • 相关阅读:
    windows 2012 r2怎么进入本地组策略
    ESXI | ESXI6.7如何在网页端添加用户并且赋予不同的权限
    exsi 6.7u2 不能向winows虚拟机发送ctrl+alt+del
    正确安装Windows server 2012 r2的方法
    gitkraken生成ssh keys并连接git
    GitKraken 快速配置 SSH Key
    寒假学习进度六
    寒假学习进度五——活动之间的跳转以及数据的传递
    寒假学习进度四(解决Android studio的com.android.support.v4.view.ViewPager报错问题)
    寒假学习进度三——安卓的一些基本组件
  • 原文地址:https://www.cnblogs.com/chiyo/p/11209325.html
Copyright © 2020-2023  润新知