• [bzoj3217]ALOEXT


      被这题虐了快两天。。。。。。。。。。。。

      找最大的异或值显然用trie。。因为还要支持插入删除修改。。所以就用平衡树套trie。

      如果旋转的话,整颗trie都要重新建,所以正常姿势是替罪羊树(虽然只是早建晚建的区别= =)

      看了学长的解题报告后才敢用treap= =。。结果就陷入了无尽的调试中TAT..代码能力还是拙计...前前后后改了两天,大概得有8h+吧。。。

      具体做法:每个treap的节点上建一颗高度为20的trie(因为数的大小<2^20),在trie中插入treap节点所在子树中的所有数字。

      显然trie里面得动态开节点,而且还要垃圾回收。旋转的时候暴力重构trie就好了(注意常数)

      垃圾回收千万别调stl的队列TAT。。。会慢一半以上。。自己写个栈就一行。。为何要去亲身感受stl的常数TAT

      查询的时候就把在treap里拆成一个个对应的小区间和节点,用数组存着,顺便求出第二大的数值。计算异或值的时候可以一个一个跑,也可以一次在一颗trie上跑完。后一种的话要记得把已经无法匹配的节点丢掉,并且速度也比前一种快一些。。

      感觉自己的常数已经没法再压了。。然而跑了倒数第2。。orz

      运行了下云神的代码发现自己的删除操作慢了一倍多= =。。。至今原因不明TAT。。而且数据很多都是删除、插入的操作(针对替罪羊树)TAT。。其他操作还不慢。

      一开始建treap的时候记得递归建树(最主要的是避免无谓的旋转)。。

    代码长度还好。。不到6k。。我是应该高兴还是悲伤呢。。。

    话说原来代码可读性这种东西真的是毫无下限的啊。。。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #include<queue>
      7 #define get top?st[top--]:++tt
      8 using namespace std;
      9 const int maxn=100033<<1;
     10 const int maxm=maxn*160;
     11 int two[21],len;
     12 int ch[2][maxm],sm[maxm],tt;int st[maxm],top;
     13 int l[maxn],r[maxn],num[maxn],sz[maxn],mx1[maxn],mx2[maxn],rnd[maxn],rt[maxn],tot,nowmx1,nowmx2;
     14 int i,j,n,m,x,y,root,ans,tmp,V;
     15 int ra;char rx;
     16 inline int read(){
     17     rx=getchar(),ra=0;
     18     while(rx<'0'||rx>'9')rx=getchar();
     19     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     20 }
     21 inline void ins(int &rt,int v){
     22     if(!rt)rt=get;int x=rt;++sm[x];
     23     for(register int i=19;i>=0;i--)
     24         if(v&two[i])++sm[ ch[1][x] ? x=ch[1][x] : x=ch[1][x]=get ];else
     25         ++sm[ ch[0][x]?x=ch[0][x]:x=ch[0][x]=get ];
     26 }
     27 inline void clr(int &x){
     28     st[++top]=x,sm[x]=0;
     29     if(ch[0][x])clr(ch[0][x]);if(ch[1][x])clr(ch[1][x]);
     30     x=0;
     31 }
     32 inline void del(int x,int v){
     33     --sm[x];bool k;
     34     for(register int i=19,j=x;i>=0;j=x,i--){
     35         if(v&two[i])x=ch[k=1][j];else x=ch[k=0][j];
     36         if(!(--sm[x])){ch[k][j]=0,clr(x);return;}
     37     }
     38 }
     39 inline void update(int &x,int l,int r){//merge
     40     x=get,sm[x]=sm[l]+sm[r];
     41     if(ch[0][l]||ch[0][r])update(ch[0][x],ch[0][l],ch[0][r]);
     42     if(ch[1][l]||ch[1][r])update(ch[1][x],ch[1][l],ch[1][r]);
     43 }
     44 
     45 inline void upd(int x,int l,int r){
     46     sz[x]=sz[l]+sz[r]+1;
     47     if(mx1[l]<mx1[r])mx1[x]=mx1[r],mx2[x]=mx1[l];else mx1[x]=mx1[l],mx2[x]=mx1[r];
     48     if(mx2[l]<mx2[r])if(mx2[x]<mx2[r])mx2[x]=mx2[r];else;
     49         else if(mx2[x]<mx2[l])mx2[x]=mx2[l];
     50     if(mx1[x]<num[x])mx2[x]=mx1[x],mx1[x]=num[x];else
     51     if(mx2[x]<num[x])mx2[x]=num[x];
     52 }
     53 inline void lturn(int &x,int R){
     54     r[x]=l[R],l[R]=x,sz[R]=sz[x],mx1[R]=mx1[x],mx2[R]=mx2[x],
     55     clr(rt[R]),rt[R]=rt[x],upd(x,l[x],r[x]),update(rt[x],rt[l[x]],rt[r[x]]),ins(rt[x],num[x]),x=R;
     56 }
     57 inline void rturn(int &x,int L){
     58     l[x]=r[L],r[L]=x,sz[L]=sz[x],mx1[L]=mx1[x],mx2[L]=mx2[x],
     59     clr(rt[L]),rt[L]=rt[x],upd(x,l[x],r[x]),update(rt[x],rt[l[x]],rt[r[x]]),ins(rt[x],num[x]),x=L;
     60 }
     61 inline void insert(int &x,int po,int v){
     62     if(!x){x=++tot,rnd[x]=(rand()>>1)+tot,num[x]=mx1[x]=v,sz[x]=1,ins(rt[x],v);return;}
     63     sz[x]++,ins(rt[x],v);
     64     if(v>mx1[x])mx2[x]=mx1[x],mx1[x]=v;else if(v>mx2[x])mx2[x]=v;
     65     if(po>sz[l[x]]+1){
     66         insert(r[x],po-sz[l[x]]-1,v);
     67         if(rnd[r[x]]<rnd[x])lturn(x,r[x]);
     68     }else{
     69         insert(l[x],po,v);
     70         if(rnd[l[x]]<rnd[x])rturn(x,l[x]);
     71     }
     72 }
     73 inline void change(int &x,int po,int v){
     74     if(sz[l[x]]+1==po)V=num[x],num[x]=v;else
     75     if(po<=sz[l[x]])change(l[x],po,v);
     76     else change(r[x],po-sz[l[x]]-1,v);
     77     del(rt[x],V),ins(rt[x],v),upd(x,l[x],r[x]);
     78 }
     79 inline void delet(int &x,int po){
     80     if(sz[l[x]]+1==po){
     81         if(!(l[x]&&r[x]))V=num[x],clr(rt[x]),x=l[x]|r[x];else
     82             if(rnd[l[x]]<rnd[r[x]])rturn(x,l[x]),delet(x,po);
     83             else lturn(x,r[x]),delet(x,po);
     84     }else if(po<=sz[l[x]])delet(l[x],po),upd(x,l[x],r[x]),del(rt[x],V);
     85     else delet(r[x],po-sz[l[x]]-1),upd(x,l[x],r[x]),del(rt[x],V);
     86 }
     87 int st1[maxn],st2[maxn],top1,top2;
     88 inline void getmx(int x,int L,int R){
     89     if(L==1&&R==sz[x]){
     90         st1[++top1]=rt[x];
     91         if(mx1[x]>nowmx1)nowmx2=nowmx1,nowmx1=mx1[x];else if(mx1[x]>nowmx2)nowmx2=mx1[x];
     92         if(mx2[x]>nowmx2)nowmx2=mx2[x];
     93         return;
     94     }
     95     if(L>sz[l[x]]+1)getmx(r[x],L-sz[l[x]]-1,R-sz[l[x]]-1);
     96     else if(R<=sz[l[x]])getmx(l[x],L,R);
     97     else{
     98         if(num[x]>nowmx1)nowmx2=nowmx1,nowmx1=num[x];else if(num[x]>nowmx2)nowmx2=num[x];
     99         st2[++top2]=num[x];
    100         if(L<=sz[l[x]])getmx(l[x],L,sz[l[x]]);if(R>sz[l[x]]+1)getmx(r[x],1,R-sz[l[x]]-1);
    101     }
    102 }
    103 inline int query(int l,int r){
    104     nowmx1=nowmx2=top1=top2=0,getmx(root,l,r);
    105     register int i,j,tmp;int ans=0,now=0;bool k,flag;
    106     for(;top2;top2--)if((nowmx2^st2[top2])>ans)ans=nowmx2^st2[top2];
    107     for(i=19;i>=0&&top1&&(now+two[i+1]-1>ans);--i){
    108         for(k=!(nowmx2&two[i]),j=top1,flag=0;j;--j)if(ch[k][st1[j]]){flag=1;break;}
    109         for(j=1,tmp=top1,top1=0,now+=flag?two[i]:0,k^=!flag;j<=tmp;++j)if(ch[k][st1[j]])st1[++top1]=ch[k][st1[j]];
    110     }
    111     return now<ans?ans:now;
    112 }
    113 inline void build(int L,int R,int &x,int fa){
    114     if(L>R)return;
    115     x=(L+R)>>1;tot++;
    116     if(L<R)build(L,x-1,l[x],x),num[x]=read(),build(x+1,R,r[x],x),upd(x,l[x],r[x]),update(rt[x],rt[l[x]],rt[r[x]]),ins(rt[x],num[x]);
    117     else mx1[x]=num[x]=read(),sz[x]=1,ins(rt[x],num[x]);
    118     rnd[x]=rnd[fa]+rand()&23;
    119 }
    120 
    121 char s[15];int LEN;
    122 inline void outx(int x){
    123     if(!x){puts("0");return;}
    124     while(x)s[LEN++]=x%10,x/=10;
    125     while(LEN)putchar(s[--LEN]+48);putchar('
    ');
    126 }
    127 int main(){
    128     for(i=0;i<=20;i++)two[i]=1<<i;
    129     n=read(),m=read();char id;
    130     build(1,n,root,0);
    131     while(m--){
    132         for(id=getchar();id<'A'||id>'Z';id=getchar());
    133         x=read()+ans;if(x>=sz[root])x%=sz[root];
    134         if(id!='D'){
    135             y=read()+ans;
    136             if(id!='F')if(y>=1048576)y%=1048576;else;
    137             else if(y>=sz[root])y%=sz[root];
    138         }
    139         x++;if(id=='F')y++;
    140         if(id=='I')insert(root,x,y);
    141         if(id=='D')delet(root,x);
    142         if(id=='C')change(root,x,y);
    143         if(id=='F'){if(x>y)swap(x,y);ans=query(x,y),outx(ans);}
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    Struts2 语法--action
    react ref获取dom对象
    react 简单的用函数调出ui显示
    express.js graphql express-graphql
    Nestjs 增加全局前缀
    react使用BrowserRouter打包后,刷新页面出现404
    在node环境使用axios发送文件
    Nest js 使用axios模块
    Flutter For Web
    css实现开关效果
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5146690.html
Copyright © 2020-2023  润新知