您的位置:首页 > 其它

[题解]bzoj3600 没有人的算数

2017-08-17 09:53 204 查看

Description





Solution

%%%黄学长

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=500010;
int n,m,mx[maxn<<2],pos[maxn];
double val[maxn];

template<typename T>inline void read(T &x){
T f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
x*=f;
}

struct Data{
int fir,sec;
bool operator<(Data b){
if(val[fir]==val[b.fir])return val[sec]<val[b.sec];
return val[fir]<val[b.fir];
}
bool operator==(Data b){
if(val[fir]!=val[b.fir]||val[sec]!=val[b.sec])return false;
return true;
}
};
struct ScapeGoat{
int id,A[maxn<<1],top,sum,root;
double idll,idrr;
int size[maxn<<1],ch[maxn<<1][2],fa[maxn<<1];
Data a[maxn<<1];
ScapeGoat(){
id=top=sum=root=0;
memset(size,0,sizeof size);
memset(ch,0,sizeof ch);
memset(a,0,sizeof a);
memset(fa,0,sizeof fa);
}
bool Bad(int x){
return max(size[ch[x][0]],size[ch[x][1]])>0.75*size[x]+4;
}
int Build(int f,int l,int r,double ll,double rr){
if(l>r)return 0;
int mid=(l+r)>>1,x=A[mid];
double mv=(ll+rr)/2.0;
fa[x]=f;val[x]=mv;
ch[x][0]=Build(x,l,mid-1,ll,mv);
ch[x][1]=Build(x,mid+1,r,mv,rr);
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
return x;
}
void Dfs(int x){
if(!x)return;
Dfs(ch[x][0]);ch[x][0]=0;
A[++top]=x;
Dfs(ch[x][1]);ch[x][1]=0;
}
void ReBuild(int x,double ll,double rr){
top=0;Dfs(x);
int p=(x==ch[fa[x]][1]);
if(fa[x])ch[fa[x]][p]=Build(fa[x],1,top,ll,rr);
else root=Build(0,1,top,ll,rr);
}
int Insert(int &x,int f,double ll,double rr,Data v){
double mv=(ll+rr)/2.0;
if(!x){
val[x=++sum]=mv;a[x]=v;
size[x]=1;fa[x]=f;
return x;
}
int p;
if(v==a[x])return x;
else{
size[x]++;
if(a[x]<v)p=Insert(ch[x][1],x,mv,rr,v);
else p=Insert(ch[x][0],x,ll,mv,v);
}
if(Bad(x))id=x,idll=ll,idrr=rr;
return p;
}
}sg;

void Modify(int x,int l,int r,int p){
if(l==r)return mx[x]=l,void();
int mid=(l+r)>>1;
if(p<=mid)Modify(x<<1,l,mid,p);
else Modify(x<<1|1,mid+1,r,p);
int a=mx[x<<1],b=mx[x<<1|1];
if(val[pos[a]]>=val[pos[b]])mx[x]=a;
else mx[x]=b;
}
int Query(int x,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr)return mx[x];
int mid=(l+r)>>1;
int p=0,ans=0;
if(ql<=mid)ans=Query(x<<1,l,mid,ql,qr);
if(qr>mid){
p=Query(x<<1|1,mid+1,r,ql,qr);
if(!ans)ans=p;
else if(val[pos[ans]]<val[pos[p]])ans=p;
}
return ans;
}

int main(){
read(n);read(m);
sg.Insert(sg.root,0,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);
while(m--){
char opt[10];
int l,r,k;
scanf("%s",opt);read(l);read(r);
if(opt[0]=='C'){
read(k);sg.id=0;
pos[k]=sg.Insert(sg.root,0,0,1,Data{pos[l],pos[r]});
if(sg.id)sg.ReBuild(sg.id,sg.idll,sg.idrr);
Modify(1,1,n,k);
}
else printf("%d\n",Query(1,1,n,l,r));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: