【bzoj3600】没有人的算术
因为阿咸,所以不会写题解。
大概就是平衡树维护大小关系然后随意线段树就好。
每次更新一下线段树上的区间max
#include<bits/stdc++.h> #define ll long long #define alpha 0.7 #define maxn 500005 #define INF 1ll<<60 using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll tag[maxn]; struct node{ int first,second; node(int first,int second):first(first),second(second){}; node(){}; friend bool operator == (node A,node B){ return (A.first==B.first)&&(A.second==B.second); } friend bool operator < (node A,node B){ if(tag[A.first]==tag[B.first])return tag[A.second]<tag[B.second]; return tag[A.first]<tag[B.first]; } }; int n,m,tmp,root,pos[maxn]; struct sctree{ int top,cnt,size[maxn],id[maxn],ch[maxn][2]; node val[maxn]; inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;} inline void build(int &x,int l,int r,ll lv,ll rv){ if(l>r){x=0;return;} if(l==r){ x=id[l];size[x]=1; tag[x]=lv+rv>>1; ch[x][0]=ch[x][1]=0; return; } int mid=l+r>>1; x=id[mid];tag[x]=lv+rv>>1; build(ch[x][0],l,mid-1,lv,tag[x]-1); build(ch[x][1],mid+1,r,tag[x]+1,rv); pushup(x); } inline void dfs(int x){ if(!x)return; dfs(ch[x][0]); id[++top]=x; dfs(ch[x][1]); } inline void rebuild(int &x,ll lv,ll rv){ top=0; dfs(x); build(x,1,top,lv,rv); } inline int insert(int &x,ll lv,ll rv,node v){ if(!x){ x=++cnt;size[x]=1; tag[x]=lv+rv>>1; val[x]=v; return x; } if(val[x]==v)return x; int p; ll mid=lv+rv>>1; if(v<val[x])p=insert(ch[x][0],lv,mid-1,v); else p=insert(ch[x][1],mid+1,rv,v); pushup(x); if(1.0*size[x]*alpha>1.0*max(size[ch[x][0]],size[ch[x][1]])){ if(tmp){ if(ch[x][0]==tmp)rebuild(ch[x][0],lv,mid-1); else rebuild(ch[x][1],mid+1,rv); tmp=0; } }else tmp=x; return p; } }T1; int Max; struct Segment_Tree{ int mx[maxn]; inline void pushup(int o){ int ls=mx[o<<1],rs=mx[o<<1|1]; if(tag[pos[ls]]<tag[pos[rs]])mx[o]=rs;else mx[o]=ls; } inline void build(int o,int l,int r){ if(l==r){ mx[o]=l; return; } int mid=l+r>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); pushup(o); } inline void change(int o,int l,int r,int x){ if(l==r){ mx[o]=l; return; } int mid=l+r>>1; if(x<=mid)change(o<<1,l,mid,x); else change(o<<1|1,mid+1,r,x); pushup(o); } inline void query(int o,int l,int r,int x,int y){ if(x<=l&&r<=y){ if(tag[pos[Max]]<tag[pos[mx[o]]])Max=mx[o]; return; } int mid=l+r>>1; if(y<=mid)query(o<<1,l,mid,x,y); else if(x>mid)query(o<<1|1,mid+1,r,x,y); else { query(o<<1,l,mid,x,mid); query(o<<1|1,mid+1,r,mid+1,y); } } }T2; char ch[2]; int main(){ n=read();m=read();tag[0]=-1; T1.insert(root,0,INF,node(0,0)); for(int i=1;i<=n;++i)pos[i]=1; T2.build(1,1,n); int f1,f2,f3; for(int i=1;i<=m;++i){ scanf("%s",ch);f1=read();f2=read(); if(ch[0]=='C'){ f3=read(); pos[f3]=T1.insert(root,0,INF,node(pos[f1],pos[f2])); if(tmp){T1.rebuild(root,0,INF);tmp=0;} T2.change(1,1,n,f3); }else{ Max=0; T2.query(1,1,n,f1,f2); printf("%d\n",Max); } } return 0; }