树状数组上二分

树状数组上二分

联考D1T1卡常技巧

  • 左半边的和它就等于a[mid]。

具体看实现

普通平衡树

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int read(){
	int x=0,pos=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
	return pos?x:-x;
} 
const int N=1<<25,p=1e7+20;
int a[N+1];
void add(int x,int c){
	for(x+=p;x<=N;x+=x&(-x)) a[x]+=c;
}
int query(int x){
	int res=0;for(x+=p;x;x-=x&(-x)) res+=a[x];return res;
}
int kth(int k){
	int l=1,r=N;
	while(l^r){
		int mid=(l+r)>>1;
		if(a[mid]<k) k-=a[mid],l=mid+1;
		else r=mid;
	}
	return l-p;
}
int main(){
	int n=read();
	while(n--){
		int opt=read(),x=read();
		if(opt==1) add(x,1);
		if(opt==2) add(x,-1);
		if(opt==3) printf("%d\n",query(x-1)+1);
		if(opt==4) printf("%d\n",kth(x));
		if(opt==5) printf("%d\n",kth(query(x-1)));
		if(opt==6) printf("%d\n",kth(query(x)+1)); 
	}
	return 0;
}
posted @ 2020-06-22 09:42  lcyfrog  阅读(1109)  评论(0编辑  收藏  举报