替罪羊树套Trie,Trie合并用线段树合并,注意常数优化。

顺便AC800题纪念~~~

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=200010,inf=19,M=32000010;
struct info{
int v1,v2;
info(){v1=v2=0;}
info(int _v1,int _v2){v1=_v1,v2=_v2;}
}maxv;
inline info merge(info a,info b){
if(b.v1>a.v1){
a.v2=b.v2>a.v1?b.v2:a.v1;
a.v1=b.v1;
}else if(b.v1>a.v2)a.v2=b.v1;
return a;
}
struct node{int l,r,v;node(){}node(int _l,int _r,int _v){l=_l,r=_r,v=_v;}}T[M];
int rub,getn[M];
const double A=0.8;
int size[N],real[N],ex[N],son[N][2],val[N],f[N],tot,root,id[N],cnt;
info mv[N];
int h[N],pool[N];
int ans,cntpool,cntone,one[N];
int n,q,x,y,i,Pow[20],Inv[20];char ch;
//Trie begin
inline void Max(int&a,int b){if(a<b)a=b;}
inline int Newtrienode(int l,int r,int v){
int x=getn[rub--];
T[x]=node(l,r,v);
return x;
}
void Ins(int&x,int a,int c,int p){
if(!x)x=Newtrienode(0,0,0);
T[x].v+=p;
if(~a)Ins(c&Pow[a]?T[x].r:T[x].l,a-1,c,p);
}
int Merge(int x,int y){
if(!x&&!y)return 0;
return Newtrienode(Merge(T[x].l,T[y].l),Merge(T[x].r,T[y].r),T[x].v+T[y].v);
}
inline int Ask(int x,int c){
int t=1048575,a;
for(a=inf;t>ans&&~a;a--)if(c&Pow[a]){
if(T[T[x].l].v)x=T[x].l;else t&=Inv[a],x=T[x].r;
}else{
if(T[T[x].r].v)x=T[x].r;else t&=Inv[a],x=T[x].l;
}
return t;
}
inline void Ask(int c){
int i;
for(i=1;i<=cntone;i++)Max(ans,one[i]^c);
for(i=1;i<=cntpool;i++)Max(ans,Ask(pool[i],c));
}
void deltree(int x){
if(!x)return;
deltree(T[x].l);deltree(T[x].r);
getn[++rub]=x;
}
//Trie end
//Scapegoat begin
inline void up(int x){
mv[x]=info(ex[x]?val[x]:0,0);
if(son[x][0])mv[x]=merge(mv[x],mv[son[x][0]]);
if(son[x][1])mv[x]=merge(mv[x],mv[son[x][1]]);
}
inline int newnode(int p,int fa){
int x=++tot;
f[x]=fa;size[x]=real[x]=ex[x]=1;son[x][0]=son[x][1]=0;
val[x]=p;
mv[x]=info(p,0);
Ins(h[x]=0,inf,p,1);
return x;
}
inline int Newnode(int x,int fa){
f[x]=fa;size[x]=1;real[x]=ex[x];son[x][0]=son[x][1]=0;
mv[x]=info(ex[x]?val[x]:0,0);
h[x]=0;
return x;
}
int ins(int x,int p,int b){
size[x]++;real[x]++;mv[x]=merge(mv[x],info(p,0));
Ins(h[x],inf,p,1);
if(!son[x][b])return son[x][b]=newnode(p,x);else return ins(son[x][b],p,b);
}
void dfs(int x){
if(son[x][0])dfs(son[x][0]);
id[++cnt]=x;
if(son[x][1])dfs(son[x][1]);
}
int build(int fa,int l,int r){
int mid=(l+r)>>1,x=Newnode(id[mid],fa);
if(l<mid)size[x]+=size[son[x][0]=build(x,l,mid-1)],real[x]+=real[son[x][0]];
if(r>mid)size[x]+=size[son[x][1]=build(x,mid+1,r)],real[x]+=real[son[x][1]];
h[x]=Merge(h[son[x][0]],h[son[x][1]]);
if(ex[x])Ins(h[x],inf,val[x],1);
up(x);
return x;
}
inline int rebuild(int x){
cnt=0;dfs(x);
for(int i=1;i<=cnt;i++)deltree(h[id[i]]);
return build(f[x],1,cnt);
}
inline int kth(int k,int p){
int x=root,rank;
while(1){
size[x]++;real[x]++;mv[x]=merge(mv[x],info(p,0));Ins(h[x],inf,p,1);
rank=real[son[x][0]]+1;
if(k==rank&&ex[x])return x;
if(k<rank)x=son[x][0];else k-=rank+ex[x]-1,x=son[x][1];
}
}
inline void kthchange(int k,int p){
int x=root,rank,del;
while(1){
rank=real[son[x][0]]+1;
if(k==rank&&ex[x])break;
if(k<rank)x=son[x][0];else k-=rank+ex[x]-1,x=son[x][1];
}
for(del=val[x],val[x]=p;x;x=f[x])Ins(h[x],inf,del,-1),Ins(h[x],inf,p,1),up(x);
}
inline void kthdel(int k){
int x=root,rank,del;
while(1){
rank=real[son[x][0]]+1;
if(k==rank&&ex[x])break;
if(k<rank)x=son[x][0];else k-=rank+ex[x]-1,x=son[x][1];
}
for(del=val[x],ex[x]=0;x;x=f[x])real[x]--,Ins(h[x],inf,del,-1),up(x);
}
inline void kthins(int k,int p){
if(!root){root=newnode(p,0);return;}
int x;
if(k==1)x=ins(root,p,0);
else if(k>n)x=ins(root,p,1);
else{
x=kth(k,p);
if(son[x][0])x=ins(son[x][0],p,1);else{
son[x][0]=newnode(p,x);
x=son[x][0];
}
}
int z=x,deep=0;while(f[z])z=f[z],deep++;
if(deep<log(tot)/log(1/A))return;
while((double)size[son[x][0]]<A*size[x]&&(double)size[son[x][1]]<A*size[x])x=f[x];
if(!x)return;
if(x==root){root=rebuild(x);return;}
int y=f[x],b=son[y][1]==x,now=rebuild(x);
son[y][b]=now;
}
inline void ask(int x,int a,int b,int c,int d){
if(!x)return;
if(c<=a&&b<=d){maxv=merge(maxv,mv[x]);if(h[x])pool[++cntpool]=h[x];return;}
int mid=a+real[son[x][0]];
if(ex[x]&&c<=mid&&mid<=d)maxv=merge(maxv,info(val[x],0)),one[++cntone]=val[x];
if(c<mid)ask(son[x][0],a,mid-1,c,d);
if(d>=mid+ex[x])ask(son[x][1],mid+ex[x],b,c,d);
}
//Scapegoat end
inline void read(int&a){
char ch;while(!(((ch=getchar())>='0')&&(ch<='9')));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))(a*=10)+=ch-'0';
}
int main(){
for(Pow[0]=i=1;i<=inf;i++)Pow[i]=Pow[i-1]<<1;
for(i=0;i<=inf;i++)Inv[i]=Pow[i]^1048575;
for(i=1;i<M;i++)getn[++rub]=i;
read(n);read(q);
for(i=1;i<=n;i++)read(val[i]),id[i]=i,ex[i]=1;
root=build(0,1,tot=n);
while(q--){
while(!(((ch=getchar())=='D')||(ch=='F')||(ch=='C')||(ch=='I')));
read(x);
if(ch!='D')read(y);
if(ch=='F'){
x=(x+ans)%n,y=(y+ans)%n;
maxv=info();cntpool=cntone=0;
ask(root,1,n,x+1,y+1);
ans=0;
Ask(maxv.v2);
printf("%d\n",ans);
}else if(ch=='C')x=(x+ans)%n,y=(y+ans)&1048575,kthchange(x+1,y);
else if(ch=='I')x=(x+ans)%n,y=(y+ans)&1048575,kthins(x+1,y),n++;
else x=(x+ans)%n,kthdel(x+1),n--;
}
return 0;
}

  

BZOJ3217 : ALOEXT的更多相关文章

  1. 【BZOJ3217】ALOEXT 替罪羊树+Trie树

    [BZOJ3217]ALOEXT Description taorunz平时最喜欢的东西就是可移动存储器了……只要看到别人的可移动存储器,他总是用尽一切办法把它里面的东西弄到手. 突然有一天,taor ...

  2. 【BZOJ3217】ALOEXT 分块

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3217 分块过掉辣!!!!!!$O(n^{1.5}+q\times \sqrt{n})$的 ...

  3. 【bzoj3217】ALOEXT 替罪羊树套Trie树

    题目描述 taorunz平时最喜欢的东西就是可移动存储器了……只要看到别人的可移动存储器,他总是用尽一切办法把它里面的东西弄到手. 突然有一天,taorunz来到了一个密室,里面放着一排可移动存储器, ...

  4. bzoj 3217: ALOEXT

    将此神题作为博客园的第一篇文章,至此,数据结构基本学完了(或者说数据结构轮流虐了我一次!) 人生第一道7K代码题! 没什么,就是treap套个trie,然后tle是因为一定要用指针当时p党谁会用那么丑 ...

  5. BZOJ 3217: ALOEXT (块状链表套trie)

    第一次写块状链表,发现还挺好写的,但是一点地方写错加上强制在线就会各种姿势WA/TLE/RE爆- 想法就是分块后,在每一个块上维护最大值和次大值,还在每一个块上维护一棵trie树来求异或最大值.散块直 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. 通过IIS调试ASP.NET项目

    当我们使用Visual Studio调试的时候,通常我们会选择VS自带的ASP.NET Developerment Server(也是默认选项),当第一次调试的时候(按F5或Ctrl+F5不调试直接打 ...

  2. 开发jquery tab 插件

    开发最简单的效果- -,基本构架 html,可以换更有意义的结构,这里demo,就简单写,不考虑SEO <div id="tab-hd"> <div class= ...

  3. 如何高效利用GitHub

    是Github,让社会化编程成为现实.本文尝试谈谈GitHub的文化.技巧与影响. Q1:GitHub是什么 Q2:GitHub风格 Q3: 在GitHub,如何跟牛人学习 Q4: 享受纯粹的写作与演 ...

  4. spring boot实战(第十二篇)整合RabbitMQ

    前言 最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法.Java客户端API介绍.spring Boot与RabbitMQ整 ...

  5. Java程序编译和运行的过程

    Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

  6. object-c学习笔记

    原文地址 最近开始学习object-c,分享一下学习oc的经验以及对oc的理解,其中难免会有错误,请大家理解. 对初学者来说,objective-c存在了很多令人费解的写法,当然也包括我! 我刚开始看 ...

  7. 使用Memory Analyzer tool(MAT)分析内存泄漏(二)

    转载自:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html 前言的前言 写blog就是好,在大前提下可以想说什么写什么,不像投稿那 ...

  8. 爱情之路(codevs 2070)

    题目描述 Description yh非常想念他的女朋友小y,于是他决定前往小y所在的那块大陆. 小y所在的大陆共有n个城市,m条双向路,每条路连接一个或两个城市.经过一条路ei需要耗费时间ti.此外 ...

  9. 解决页面插入HTML代码后错位(HTML代码里的标签不完整导致错位)

    这个的例子是从数据库读取出来的数据内容包含HTML导致页面错位问题! 解决办法如下: 首先过滤掉会跟JS冲突的字符,C#代码如下: string htmlc = Model.HtmlContents. ...

  10. phpstorm取消自动保存并标识修改的文件为星星标记

    PhpStorm是一个轻量级且便捷的PHP IDE,其旨在提供用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查. 自从使用上了phpstrom后就放弃了zendstudio, ...