线段树套替罪羊树求助
查看原帖
线段树套替罪羊树求助
32490
memory_frv楼主2021/8/25 16:19

样例没过,但是不知道问题在哪里啊,感觉都挺对的,救救孩子吧

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=5e4+5;
const double alpha=0.7;
int cnt,ldr[100001],rt,num[100001];
struct scape{
	int ls,rs,w,wn,s,sz,sd;
}t[MAXN*30];
inline void calc(int k){
	t[k].s=t[t[k].ls].s+t[t[k].rs].s+1;
	t[k].sz=t[t[k].ls].sz+t[t[k].rs].sz+t[k].wn;
	t[k].sd=t[t[k].ls].sd+t[t[k].rs].sd+(t[k].wn!=0);
}
inline int newnode(int w){
	++cnt;
	t[cnt].ls=t[cnt].rs=0;
	t[cnt].w=w;t[cnt].wn=t[cnt].s=t[cnt].sz=t[cnt].sd=1;
	return cnt;
}
inline bool check(int k){
	return t[k].wn&&(alpha*t[k].s<=(double)max(t[t[k].ls].s,t[t[k].rs].s)||(double)t[k].sd<=alpha*t[k].s);
}
inline void pai(int& ldc,int k){
	if(!k) return ;
	pai(ldc,t[k].ls);
	if(t[k].wn) ldr[ldc++]=k;
	pai(ldc,t[k].rs);
}
inline int rebuild(int l,int r){
	int mid=(l+r)/2;
	if(l>=r) return 0;
	t[ldr[mid]].ls=rebuild(l,mid);
	t[ldr[mid]].rs=rebuild(mid+1,r);
	calc(ldr[mid]);
	return ldr[mid];
}
inline void re(int& k){
	int ldc=0;
	pai(ldc,k);
	k=rebuild(0,ldc);
}
inline void ins(int& k,int p){
	if(!k) k=newnode(p);
	else{
		if(p==t[k].w) t[k].wn++;
		else if(p<t[k].w) ins(t[k].ls,p);
		else ins(t[k].rs,p);
		calc(k);
		if(check(k)) re(k);
	}
}
inline void del(int& k,int p){
	if(!k) return ;
	else{
		if(t[k].w==p){
			if(t[k].wn) t[k].wn--;
		}else if(p<t[k].w) del(t[k].ls,p);
		else del(t[k].rs,p);
		calc(k);
		if(check(k)) re(k);
	}
}
inline int upb(int k,int p){
	if(!k) return 1;
	else if(t[k].w==p&&t[k].wn) return t[t[k].ls].sz+1+t[k].wn;
	else if(t[k].w<p) return t[t[k].ls].sz+t[k].wn+upb(t[k].rs,p);
	else return upb(t[k].ls,p);
}
inline int fpb(int k,int p){
	if(!k) return 0;
	else if(t[k].w==p&&t[k].wn) return t[t[k].ls].sz;
	else if(t[k].w<p) return t[t[k].ls].sz+t[k].wn+fpb(t[k].rs,p);
	else return fpb(t[k].ls,p);
}
inline int at(int k,int p){
	if(!k) return 0;
	else if(t[t[k].ls].sz<p&&t[t[k].ls].sz+t[k].wn>=p) return t[k].w;
	else if(t[t[k].ls].sz+t[k].wn<p) return at(t[k].rs,p-t[t[k].ls].sz-t[k].wn);
	else return at(t[k].ls,p);
}
inline int qianqu(int k,int p){
	return at(k,fpb(k,p));
}
inline int houji(int k,int p){
	return at(k,upb(k,p));
}
struct segment{
	int l,r,root;
}a[MAXN*10];
inline void build(int p,int l,int r){
	a[p].l=l,a[p].r=r;
	for(int i=l;i<=r;i++) ins(a[p].root,num[i]);
	if(l==r) return ;
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}
inline void change(int p,int x,int y){
	del(a[p].root,num[x]);
	ins(a[p].root,y);
	if(a[p].l==a[p].r) return ;
	int mid=(a[p].l+a[p].r)/2;
	if(x<=mid) change(p*2,x,y);
	if(x>mid) change(p*2+1,x,y);
}
inline int queryrank(int p,int l,int r,int k){
	if(a[p].l>r||a[p].r<l) return 0;
	if(a[p].l>=l&&a[p].r<=r){
		return fpb(a[p].root,k)+1;
	}else return queryrank(p*2,l,r,k)+queryrank(p*2+1,l,r,k);
}
inline int querynum(int l,int r,int k){
	int le=0,ri=1e8;
	while(le<ri){
	//	cout<<le<<" "<<ri<<endl;
		int mid=(le+ri+1)/2;
		if(queryrank(1,l,r,mid)<k){
			le=mid;
		}else ri=mid-1;
	}
	return ri;
}
inline int querypre(int p,int l,int r,int k){
	if(a[p].l>r||a[p].r<l) return -2147483647;
	if(a[p].l>=l&&a[p].r<=r) return qianqu(a[p].root,k);
	else return max(querypre(p*2,l,r,k),querypre(p*2+1,l,r,k));
}
inline int queryhou(int p,int l,int r,int k){
	if(a[p].l>r||a[p].r<l) return 2147483647;
	if(a[p].l>=l&&a[p].r<=r) return houji(a[p].root,k);
	else return min(queryhou(p*2,l,r,k),queryhou(p*2+1,l,r,k));
}
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) scanf("%d",&num[i]);
	build(1,1,n);
	for(int i=0;i<m;i++){
		int opt,l,r,k;
		scanf("%d%d%d",&opt,&l,&r);
		if(opt==1){
			scanf("%d",&k);
			printf("%d\n",queryrank(1,l,r,k));
		}else if(opt==2){
			scanf("%d",&k);
			printf("%d\n",querynum(l,r,k));
		}else if(opt==3){
			change(1,l,r);
		}else if(opt==4){
			scanf("%d",&k);
			printf("%d\n",querypre(1,l,r,k));
		}else{
			scanf("%d",&k);
			printf("%d\n",queryhou(1,l,r,k));
		}
	}
	return 0;
}
2021/8/25 16:19
加载中...