Description
给定一个序列,要求兹磁一下操作
- 插入一个数
- 删除一个数
- 修改一个数
- 查询区间次大值与另一数字异或的最大值
Solution
都是套路。。真·oi中的解析几何
唯一需要注意的就是替罪羊树上删除只打标记,我们重构的时候才真正删除,并且我写的做法需要同时维护包含删除节点的s和不包含删除节点的size,根据s判断是否重构
我也就写了6k+,我爱数据结构.jpg
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <stack>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
const double alpha=0.8;
const int N=600005;
int w[N],tot;
namespace Trie {
struct treeNode {
int son[2],size;
} t[30000005];
std:: stack <int> stack;
int tot;
int new_node() {
if (stack.empty()) return ++tot;
int x=stack.top(); stack.pop();
return x;
}
void reuse(int x) {
if (t[x].son[0]) reuse(t[x].son[0]);
if (t[x].son[1]) reuse(t[x].son[1]);
t[x].son[0]=t[x].son[1]=t[x].size=0;
stack.push(x);
}
void ins(int &root,int v,int s) {
if (!root) root=new_node();
int x=root; t[x].size+=s;
drp(i,19,0) {
int k=((v>>i)&1);
if (!t[x].son[k]) t[x].son[k]=new_node();
x=t[x].son[k];
t[x].size+=s;
}
}
int ask(int root,int v) {
int x=root,res=0;
drp(i,19,0) {
int k=((v>>i)&1);
if (t[t[x].son[!k]].size) x=t[x].son[!k],res+=(1<<i);
else x=t[x].son[k];
}
return res;
}
}
namespace Scape {
struct treeNode {
int son[2],size,s,fa,del,mx1,mx2;
} t[N];
std:: vector <int> p,q,u;
int rt[N],vec[N],R,root;
bool cmp(int x,int y) {
return x>y;
}
void push_up(int x) {
t[x].size=!t[x].del; u.clear();
t[x].s=1;
int ls=t[x].son[0],rs=t[x].son[1];
if (ls) {
t[x].s+=t[ls].s;
t[x].size+=t[ls].size;
u.push_back(t[ls].mx1);
u.push_back(t[ls].mx2);
}
if (rs) {
t[x].s+=t[rs].s;
t[x].size+=t[rs].size;
u.push_back(t[rs].mx1);
u.push_back(t[rs].mx2);
}
u.push_back(w[x]); u.push_back(0);
std:: sort(u.begin(), u.end(),cmp);
t[x].mx1=u[0]; t[x].mx2=u[1];
}
void ins(int x,int k,int nw) {
Trie:: ins(rt[x],w[nw],1);
int tmp=t[t[x].son[0]].size+(!t[x].del);
if (tmp>=k) {
if (!t[x].son[0]) {
t[x].son[0]=nw; t[nw].fa=x; t[nw].size=1;
t[nw].mx1=w[nw]; t[nw].mx2=0;
Trie:: ins(rt[nw],w[nw],1);
} else ins(t[x].son[0],k,nw);
} else {
if (!t[x].son[1]) {
t[x].son[1]=nw; t[nw].fa=x; t[nw].size=1;
t[nw].mx1=w[nw]; t[nw].mx2=0;
Trie:: ins(rt[nw],w[nw],1);
} else ins(t[x].son[1],k-tmp,nw);
}
if (t[x].fa&&t[x].s>alpha*t[t[x].fa].s) R=t[x].fa;
push_up(x);
}
int del(int x,int k) {
int tmp=t[t[x].son[0]].size,wjp;
if (!t[x].del) {
if (tmp+1==k) {
Trie:: ins(rt[x],w[x],-1);
wjp=w[x]; w[x]=0;
t[x].del=1;
push_up(x); return wjp;
} else if (tmp>=k) wjp=del(t[x].son[0],k);
else wjp=del(t[x].son[1],k-tmp-1);
} else {
if (tmp>=k) wjp=del(t[x].son[0],k);
else wjp=del(t[x].son[1],k-tmp);
}
Trie:: ins(rt[x],wjp,-1);
if (t[x].fa&&t[x].s>alpha*t[t[x].fa].s) R=t[x].fa;
push_up(x);
return wjp;
}
int modify(int x,int k,int v) {
Trie:: ins(rt[x],v,1);
int tmp=t[t[x].son[0]].size,wjp;
if (!t[x].del) {
if (tmp+1==k) {
Trie:: ins(rt[x],w[x],-1);
wjp=w[x]; w[x]=v;
push_up(x); return wjp;
} else if (tmp>=k) wjp=modify(t[x].son[0],k,v);
else wjp=modify(t[x].son[1],k-tmp-1,v);
} else {
if (tmp>=k) wjp=modify(t[x].son[0],k,v);
else wjp=modify(t[x].son[1],k-tmp,v);
}
Trie:: ins(rt[x],wjp,-1);
push_up(x);
return wjp;
}
void dfs(int x) {
Trie:: reuse(rt[x]); rt[x]=0;
if (t[x].son[0]) dfs(t[x].son[0]);
if (!t[x].del) vec[++vec[0]]=x;
if (t[x].son[1]) dfs(t[x].son[1]);
}
int build(int l,int r) {
int mid=(l+r)>>1;
int x=vec[mid]; t[x].fa=t[x].del=0;
t[x].son[0]=t[x].son[1]=0;
if (l!=mid) t[x].son[0]=build(l,mid-1),t[t[x].son[0]].fa=x;
if (mid!=r) t[x].son[1]=build(mid+1,r),t[t[x].son[1]].fa=x;
rep(i,l,r) Trie:: ins(rt[x],w[vec[i]],1);
push_up(x); return x;
}
void rebuild() {
int ff=t[R].fa,k=(t[ff].son[1]==R);
vec[0]=0; dfs(R); R=0;
if (!vec[0]) {
if (ff) t[ff].son[k]=0;
else root=0;
return ;
}
int mid=build(1,vec[0]);
if (ff) {
t[ff].son[k]=mid;
t[mid].fa=ff;
} else root=mid;
}
void get(int x,int l,int r) {
if (r<l) return ;
if (l==1&&r==t[x].size) {
q.push_back(x); return ;
}
int a=t[t[x].son[0]].size;
if (!t[x].del&&l<=a+1&&r>=a+1) p.push_back(x);
get(t[x].son[0],l,std:: min(a,r));
get(t[x].son[1],std:: max(1,l-a-!t[x].del),r-a-!t[x].del);
}
int solve(int l,int r) {
int ans=0,mx1=0,mx2=0;
p.clear(); q.clear();
get(root,l,r);
for (int i=0;i<q.size();++i) {
u.clear();
if (t[q[i]].mx1>mx1) mx2=std:: max(mx1,t[q[i]].mx2),mx1=t[q[i]].mx1;
else if (t[q[i]].mx1>mx2) mx2=t[q[i]].mx1;
}
for (int i=0;i<p.size();++i) {
u.clear();
if (w[p[i]]>mx1) mx2=mx1,mx1=w[p[i]];
else if (w[p[i]]>mx2) mx2=w[p[i]];
}
for (int i=0;i<p.size();++i) ans=std:: max(ans,mx2^w[p[i]]);
for (int i=0;i<q.size();++i) ans=std:: max(ans,Trie:: ask(rt[q[i]],mx2));
return ans;
}
void debug(int x) {
if (t[x].son[0]) debug(t[x].son[0]);
if (!t[x].del) printf("%d ", w[x]);
if (t[x].son[1]) debug(t[x].son[1]);
}
} ;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
int main(void) {
int n=read(),m=read(); tot=n;
rep(i,1,n) {
w[i]=read();
Scape:: vec[++Scape:: vec[0]]=i;
}
Scape:: root=Scape:: build(1,Scape:: vec[0]);
for (int opt,lastans=0,n0=n;m--;) {
for (opt=getchar();opt<'A'||opt>'Z';) opt=getchar();
int x=(read()+lastans)%n0+1;
if (opt=='I') {
int y=(read()+lastans)%1048576;
w[++tot]=y; n0++;
Scape:: ins(Scape:: root,x,tot);
} else if (opt=='D') { n0--;
Scape:: del(Scape:: root,x);
} else if (opt=='C') {
int y=(read()+lastans)%1048576;
Scape:: modify(Scape:: root,x,y);
} else {
int y=(read()+lastans)%n0+1;
lastans=Scape:: solve(x,y);
printf("%d\n", lastans);
}
if (Scape:: R) Scape:: rebuild();
// Scape:: debug(Scape:: root); puts("");
}
return 0;
}