权值线段树 91pts W#10 求调
查看原帖
权值线段树 91pts W#10 求调
558234
swa_0808楼主2023/12/16 21:16
#include <bits/stdc++.h>
using namespace std;

const int maxn=1e5+5;

int z[maxn<<1],n,op[maxn],x[maxn],xx,lc[maxn<<1],rc[maxn<<1],d[maxn<<1],b[maxn],a[maxn],num,root;

void get_sum(int rt){
	d[rt]=d[lc[rt]]+d[rc[rt]];
}

void update(int s,int t,int &p,int pos,int val){
	if(!p)	p=++num;
	if(s==t){
		d[p]+=val;
		z[p]=b[s];
		return;
	}
	int mid=s+t>>1;
	if(pos<=mid)	update(s,mid,lc[p],pos,val);
	else			update(mid+1,t,rc[p],pos,val);
	get_sum(p);
}

int query1(int s,int t,int p,int l,int r){
	if(!p)	return 0;
	if(l<=s && r>=t)	return d[p];
	int mid=s+t>>1,tot=0;
	get_sum(p);
	if(l<=mid)		tot+=query1(s,mid,lc[p],l,r);
	if(r>mid)		tot+=query1(mid+1,t,rc[p],l,r);
	return tot;
}

int query2(int s,int t,int p,int pos){
	if(!p)		return 0;
	if(s==t)	return z[p];
	get_sum(p);
	int mid=s+t>>1;
	if(pos<=d[lc[p]])	return query2(s,mid,lc[p],pos);
	else				return query2(mid+1,t,rc[p],pos-d[lc[p]]);
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)	scanf("%d%d",&op[i],&x[i]),a[i]=b[i]=x[i];
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++)	x[i]=lower_bound(b+1,b+1+len,x[i])-b;
	for(int i=1;i<=n;i++){
		if(op[i]==1)	update(1,len,root,x[i],1);
		else if(op[i]==2)	update(1,len,root,x[i],-1);
		else if(op[i]==3)	printf("%d\n",query1(1,len,root,1,x[i]-1)+1);
		else if(op[i]==4)	printf("%d\n",query2(1,len,root,a[i]));
		else if(op[i]==5)	xx=query1(1,len,root,1,x[i]-1),printf("%d\n",query2(1,len,root,xx)),xx=0;
		else				xx=query1(1,len,root,1,x[i]),printf("%d\n",query2(1,len,root,xx+1)),xx=0;
	}
	return 0;
}
2023/12/16 21:16
加载中...