BZOJ 3600 替罪羊树+线段树
思路:
当然是抄的黄学长的题解啦
//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 500005
int n,m,rt,R,top,id[N],mx[N],pos[N];
double a[N];char ch[11];
struct data{
int l,r;
friend bool operator>(data x,data y){
if(a[x.l]>a[y.l])return 1;
if(a[x.l]==a[y.l]&&a[x.r]>a[y.r])return 1;
return 0;
}
friend bool operator==(data x,data y){
if(x.l!=y.l||x.r!=y.r)return 0;
return 1;
}
};
struct SCTree{
int cnt,size[N],ls[N],rs[N];data v[N];
void dfs(int k){
if(!k)return;
dfs(ls[k]);
id[++top]=k;
dfs(rs[k]);
}
void build(int &k,int l,int r,double lv,double rv){
if(l>r){k=0;return;}
double mv=(lv+rv)/2.0;
int mid=(l+r)>>1;k=id[mid];a[k]=mv;
build(ls[k],l,mid-1,lv,mv);
build(rs[k],mid+1,r,mv,rv);
size[k]=size[ls[k]]+size[rs[k]]+1;
}
void rebuild(int &k,double lv,double rv){
top=0;dfs(k);
build(k,1,top,lv,rv);
}
int insert(int &k,double lv,double rv,data val){
double mv=(lv+rv)/2.0;
if(!k){
k=++cnt;a[k]=mv;v[k]=val,size[k]=1;
return k;
}
int p;
if(val==v[k])return k;
else{
size[k]++;
if(val>v[k])p=insert(rs[k],mv,rv,val);
else p=insert(ls[k],lv,mv,val);
}
if(size[k]*0.666>max(size[ls[k]],size[rs[k]])){
if(R){
if(ls[k]==R)rebuild(ls[k],lv,mv);
else rebuild(rs[k],mv,rv);
R=0;
}
}
else R=k;
return p;
}
}sc;
void modify(int k,int l,int r,int v){
int mid=(l+r)>>1;
if(l==r){mx[k]=l;return;}
if(v<=mid)modify(k<<1,l,mid,v);
else modify(k<<1|1,mid+1,r,v);
int x=mx[k<<1],y=mx[k<<1|1];
mx[k]=a[pos[x]]>=a[pos[y]]?x:y;
}
int query(int k,int l,int r,int x,int y){
if(l>=x&&r<=y)return mx[k];
int mid=(l+r)>>1;
if(mid<x)return query(k<<1|1,mid+1,r,x,y);
else if(mid>=y)return query(k<<1,l,mid,x,y);
else{
int p1=query(k<<1|1,mid+1,r,x,y),p2=query(k<<1,l,mid,x,y);
return a[pos[p1]]>a[pos[p2]]?p1:p2;
}
}
int main(){
scanf("%d%d",&n,&m);
a[0]=-1;
sc.insert(rt,0,1,(data){0,0});
for(int i=1;i<=n;i++)pos[i]=1;
for(int i=1;i<=n;i++)modify(1,1,n,i);
int l,r,K;
for(int i=1;i<=m;i++){
scanf("%s%d%d",ch+1,&l,&r);
if(ch[1]=='C'){
scanf("%d",&K);
pos[K]=sc.insert(rt,0,1,(data){pos[l],pos[r]});
if(R)sc.rebuild(rt,0,1),R=0;
modify(1,1,n,K);
}
else printf("%d\n",query(1,1,n,l,r));
}
}