题意:太难说了。。手动去看吧反正不是权限题。
膜拜VFK大爷的神题!
其实一开始思路挺清楚的,如果我们能做到用一个实数去代表“数”,这就是裸的动态区间最值查询。
关键是怎么用实数去表示。如果我们单纯的把两个数进行O(1)运算去得到一个实数,这样很轻松就会被卡掉,因为无论是longlong还是double都是有限度的。怎么做呢?
这里有一个技巧:我们维护一个重量平衡树,每个节点管辖一个区间,这个区间的中位数为这个点的权值,而它的左儿子管辖左半边,右儿子管辖右半边。
问题来了,这不是差不多吗?并不是这样。因为我们会重构,树高有保证,所以我们肯定能表示出每一个数,而且还是绰绰有余。
重量平衡树可以用不旋转的treap或替罪羊树。
(吐槽一句,第一次写替罪羊树,真的好TM难写啊还套了个线段树而且我常数大的飞起,写了一整天)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 500005 4 #define LL long long 5 inline LL read(){ 6 LL x=0,f=1; char a=getchar(); 7 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 8 while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); 9 return x*f; 10 } 11 int n,m; char st[5]; 12 LL MX; 13 #define SGT Scapegoat_Tree 14 #define ST Segment_Tree 15 16 namespace Scapegoat_Tree{ 17 #define eps 1e-12 18 const double alpha=0.75; 19 int ltst,wh,size=1,tmp[N],root=1,anew; 20 struct sgt{ 21 LL l,r,mid; int fir,sec; 22 int son[2],sz; 23 }tr[N]; 24 inline int dcmp(int x,int y){ 25 if(fabs((double)tr[x].sz*alpha-(double)tr[y].sz)<eps) return 0; 26 else return (double)tr[x].sz*alpha>(double)tr[y].sz?1:-1; 27 } 28 inline void update(int x){ 29 tr[x].sz=tr[tr[x].son[0]].sz+tr[tr[x].son[1]].sz+1; 30 } 31 inline bool balance(int x){ 32 return dcmp(x,tr[x].son[0])>=0 && dcmp(x,tr[x].son[1])>=0; 33 } 34 void travel(int x){ 35 if(!x) return; 36 travel(tr[x].son[0]); 37 tmp[++tmp[0]]=x; 38 travel(tr[x].son[1]); 39 } 40 void rebuild(int &x,int l,int r,LL L,LL R){ 41 if(l>r) {x=0; return;} 42 int mid=(l+r)>>1; 43 LL M=(L+R)/2; 44 x=tmp[mid]; tr[x].l=L; tr[x].r=R; tr[x].mid=M; 45 if(l==r) {tr[x].sz=1; tr[x].son[0]=0; tr[x].son[1]=0; return;} 46 rebuild(tr[x].son[0],l,mid-1,L,M); rebuild(tr[x].son[1],mid+1,r,M,R); 47 update(x); 48 } 49 void insert(int& x,LL L,LL R,int fir,int sec){ 50 if(!x) {x=++size; anew=x;tr[x]=(sgt){L,R,(L+R)/2,fir,sec,0,0,1}; return;} 51 if(tr[tr[x].fir].mid==tr[fir].mid && tr[tr[x].sec].mid==tr[sec].mid) {anew=x; return;} 52 else if(tr[tr[x].fir].mid==tr[fir].mid){ 53 if(tr[tr[x].sec].mid>tr[sec].mid) insert(tr[x].son[0],tr[x].l,tr[x].mid,fir,sec); 54 else insert(tr[x].son[1],tr[x].mid,tr[x].r,fir,sec); 55 } 56 else{ 57 if(tr[tr[x].fir].mid>tr[fir].mid) insert(tr[x].son[0],tr[x].l,tr[x].mid,fir,sec); 58 else insert(tr[x].son[1],tr[x].mid,tr[x].r,fir,sec); 59 } 60 update(x); 61 if(tr[x].son[0] && !balance(tr[x].son[0])) ltst=x,wh=0; 62 else if(tr[x].son[1] && !balance(tr[x].son[1])) ltst=x,wh=1; 63 if(x==root && !balance(x)) tmp[0]=0,travel(root),rebuild(root,1,tmp[0],1,MX); 64 } 65 } 66 namespace Segment_Tree{ 67 int a[N]; 68 struct seg{ 69 int l,r,son[2],mx_pos,num; 70 }tr[N]; 71 inline void update(int x){ 72 if(SGT::tr[tr[tr[tr[x].son[0]].mx_pos].num].mid==SGT::tr[tr[tr[tr[x].son[1]].mx_pos].num].mid){ 73 int le=tr[tr[x].son[0]].mx_pos,ri=tr[tr[x].son[1]].mx_pos; 74 tr[x].mx_pos=tr[le].l<tr[ri].l?le:ri; 75 } 76 else if(SGT::tr[tr[tr[tr[x].son[0]].mx_pos].num].mid>SGT::tr[tr[tr[tr[x].son[1]].mx_pos].num].mid) 77 tr[x].mx_pos=tr[tr[x].son[0]].mx_pos; 78 else tr[x].mx_pos=tr[tr[x].son[1]].mx_pos; 79 } 80 void build(int x,int l,int r){ 81 if(l==r) {tr[x]=(seg){l,r,0,0,x,1};return;} 82 int mid=(l+r)>>1; tr[x].l=l; tr[x].r=r; 83 tr[x].son[0]=x<<1; build(tr[x].son[0],l,mid); 84 tr[x].son[1]=x<<1|1; build(tr[x].son[1],mid+1,r); 85 update(x); 86 } 87 void modify(int x,int ai,int v){ 88 int l=tr[x].l,r=tr[x].r; 89 if(l==r) {tr[x].num=v; return;} 90 int mid=(l+r)>>1; 91 if(ai<=mid) modify(tr[x].son[0],ai,v); 92 else modify(tr[x].son[1],ai,v); 93 update(x); 94 } 95 int query(int x,int L,int R){ 96 int l=tr[x].l,r=tr[x].r; 97 if(l==L && r==R) return tr[x].mx_pos; 98 int mid=(l+r)>>1; 99 if(R<=mid) return query(tr[x].son[0],L,R); 100 else if(mid<L) return query(tr[x].son[1],L,R); 101 else{ 102 int le=query(tr[x].son[0],L,mid),ri=query(tr[x].son[1],mid+1,R); 103 if(SGT::tr[tr[le].num].mid==SGT::tr[tr[ri].num].mid) return tr[le].l<tr[ri].l?le:ri; 104 return SGT::tr[tr[le].num].mid>SGT::tr[tr[ri].num].mid?le:ri; 105 } 106 } 107 } 108 109 int main(){ 110 n=read(); m=read(); MX=1; 111 for(int i=1;i<=60;i++) MX*=2; 112 ST::build(1,1,n); SGT::tr[1]=(SGT::sgt){1,MX,(1+MX)/2,0,0,0,0,1}; 113 for(int i=1;i<=n;i++) ST::a[i]=1; 114 while(m--){ 115 scanf("%s",st); int k,l=read(),r=read(); 116 if(st[0]=='C'){ 117 k=read(); 118 l=ST::a[l]; r=ST::a[r]; SGT::ltst=0; SGT::insert(SGT::root,1,MX,l,r); 119 if(SGT::ltst) { 120 SGT::tmp[0]=0; SGT::travel(SGT::tr[SGT::ltst].son[SGT::wh]); 121 LL L=SGT::tr[SGT::tr[SGT::ltst].son[SGT::wh]].l,R=SGT::tr[SGT::tr[SGT::ltst].son[SGT::wh]].r; 122 SGT::rebuild(SGT::tr[SGT::ltst].son[SGT::wh],1,SGT::tmp[0],L,R); 123 } 124 ST::modify(1,k,SGT::anew),ST::a[k]=SGT::anew; 125 }else{ 126 int ans=ST::query(1,l,r); 127 ans=ST::tr[ans].l; 128 printf("%d ",ans); 129 } 130 } 131 return 0; 132 }