社区讨论

萌新刚学权值线段树,求调

P3369【模板】普通平衡树参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo9natfk
此快照首次捕获于
2023/10/28 14:12
2 年前
此快照最后确认于
2023/10/28 14:12
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxx=100005;
const int maxn=30000007;
int a[maxx];
int ans[maxn];
int n;
int ls(int p)
{
	return p<<1;
}
int rs(int p)
{
	return p<<1|1;
}
void pushup(int p)
{
	ans[p]=ans[ls(p)]+ans[rs(p)];
}
void build(int p,int l,int r)
{
	if(l==r)
	{
		ans[p]=0;
		return;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p);
}
void update(int p,int l,int r,int id,int x)
{
	if(l==r)
	{
		ans[p]+=x;
		return ;
	}
	int mid=(l+r)>>1;
	if(id<=mid)update(ls(p),l,mid,id,x);
	if(id>mid) update(rs(p),mid+1,r,id,x);
	pushup(p);
}
int query(int p,int l,int r,int qx,int qy)
{
	int res=0;
	if(qx<=l&&qy>=r)
	{
		return  ans[p];
	}
	int mid=(l+r)>>1;
	if(qx<=mid)res+=query(ls(p),l,mid,qx,qy);
	if(qy>mid) res+=query(rs(p),mid+1,r,qx,qy);
	return res;
}
int find(int p,int l,int r,int k)
{
	if(l==r)
	{
		return l;	
	}	
	int mid=(l+r)>>1;
	if(ans[ls(p)]>=k)find(ls(p),l,mid,k);
	if(ans[ls(p)]<k)find(rs(p),mid+1,r,k-ans[ls(p)]);
	return -1;
} 
signed main(){
	cin>>n;
	build(1,-10000007,10000007);
	while(n--)
	{
	int opt,x;
	scanf("%lld%lld",&opt,&x);
	if(opt==1)
	{
		update(1,-10000007,10000007,x,1);
	}
	if(opt==2)
	{
		update(1,-10000007,10000007,x,-1);
	}
	if(opt==3)
	{
		int cnt=0;
		cnt=query(1,-10000007,10000007,-10000007,x-1)+1;
		printf("%lld\n",cnt);
	}
	if(opt==4)
	{
		printf("%lld\n",find(1,-10000007,10000007,x));
	}
	if(opt==5)
	{
		int cnt=0;
		cnt=query(1,-10000007,10000007,-10000007,x-1);
		printf("%lld\n",find(1,-10000007,10000007,cnt));
	}
	if(opt==6)
	{
		int cnt=0;
		cnt=query(1,-10000007,10000007,-10000007,x);
		printf("%lld\n",find(1,-10000007,10000007,cnt+1));
	}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...