权值动态开点线段树,求调
查看原帖
权值动态开点线段树,求调
667180
Assassin_HG楼主2024/1/21 20:37

感觉就是第K小的数复杂化了,不知道再怎么调了

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+10;
int a[maxn],b[maxn],sum[maxn<<1],lc[maxn<<1],rc[maxn<<1];
int cnt,root,n,len;
void Push_up(int rt) {
	sum[rt] = sum[lc[rt]]+sum[rc[rt]];
}
void Modify(int &rt,int l,int r,int val) {
	if(!rt) {
		rt = ++cnt;
	}
	if(l==r) {
		sum[rt]++;
		return;
	}
	int mid = (l+r)>>1;
	if(val<=mid) {
		Modify(lc[rt],l,mid,val);
	} else {
		Modify(rc[rt],mid+1,r,val);
	}
	Push_up(rt);
}
void Delete(int &rt,int l,int r,int val) {
	if(!rt) {
		return;
	}
	if(l==r) {
		sum[rt]--;
		return;
	}
	int mid = (l+r)>>1;
	if(val<=mid) {
		Delete(lc[rt],l,mid,val);
	} else {
		Delete(rc[rt],mid+1,r,val);
	}
	Push_up(rt);
}
int Ask(int rt,int l,int r,int k) {
	if(!rt) {
		return 0;
	}
	if(l == r) {
		return l;
	}
	int mid = (l+r)>>1;
	if(k <= sum[lc[rt]]) {
		return Ask(lc[rt],l,mid,k);
	} else {
		return Ask(rc[rt],mid+1,r,k-sum[lc[rt]]);
	}
}
void Disc() {
	sort(b+1,b+n+1);
	len = unique(b+1,b+n+1)-(b+1);
}
int get(int val) {
	return lower_bound(b+1,b+len+1,val) - b;
}
int main() {
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i) {
		int op = 0,ves = 0;
		scanf("%d",&op);
		if(op==1) {
			scanf("%d",&a[i]);
			b[i] = a[i];
			Disc();
			Modify(root,1,len,get(a[i]));
		} else if(op==2) {
			scanf("%d",&ves);
			Delete(root,1,len,get(a[i]));
		} else if(op==3) {
			scanf("%d",&ves);
			printf("%d\n",Ask(root,1,len,ves));
		} else if(op==4) {
			scanf("%d",&ves);
			printf("%d\n",b[Ask(root,1,len,ves)]);
		} else if(op==5) {
			scanf("%d",&ves);
			printf("%d\n",b[Ask(root,1,len,Ask(root,1,len,ves)-1)]);
		} else {
			scanf("%d",&ves);
			printf("%d\n",b[Ask(root,1,len,Ask(root,1,len,ves)+1)]);
		}
	}
	return 0;
}
2024/1/21 20:37
加载中...