树状数组加二分,一直T
查看原帖
树状数组加二分,一直T
213196
Wens楼主2021/8/3 16:56
#include<bits/stdc++.h>
using namespace std;
const int Maxn=1e4+1;
const int INF=2147483647;

inline int Max(int a,int b){return a>b?a:b;}

inline int Read(){
	int x=0;bool w=0;char ch=0;
	while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return w?-x:x;
}
	
inline void Write(int x){
	if(x<0){x=-x;putchar('-');}
	if(x>9)Write(x/10);
	putchar(x%10+48);
	return ;
}

struct node{
	int type,x,id,rank;
}done[Maxn];
	
bool cmp1(node a,node b){return a.x<b.x;}
bool cmp2(node a,node b){return a.id<b.id;}
	
int T,n,maxn;
int tree[Maxn],rank[Maxn];
bool vis[Maxn];
	
int lowbit(int x){
	return x&(-x);
}
	
void updata(int x){
	while(x<=n){
		tree[x]+=1;
		x+=lowbit(x);
	}
	return ;
} 
int query(int x){
	int sum=0;
	while(x){
		sum+=tree[x];
		x-=lowbit(x);
	}
	return sum;
}
	
int main(){
	//freopen("1.in","r",stdin);
	T=Read();
	for(int i=1;i<=T;++i){
		done[i].type=Read();
		done[i].x=Read();
		done[i].id=i;
	}
	sort(done+1,done+1+T,cmp1);
	for(int i=1;i<=T;++i){
		if(done[i].x!=done[i-1].x){
			++n;
			rank[n]=done[i].x;
		}
		done[i].rank=n;
	}
	sort(done+1,done+1+T,cmp2);
	for(int i=1;i<=T;++i){
		if(done[i].type==1){
			Write(query(done[i].rank-1)+1);
			putchar('\n');
		}
		if(done[i].type==2){
			int l=1,r=n;
			while(l<r){
				int mid=(l+r)>>1;
				if(query(mid)>=done[i].x)r=mid;
				else l=mid+1;
			}
			Write(rank[l]);
			putchar('\n');
		}
		if(done[i].type==3){
			int d=0;
			for(int j=done[i].rank-1;j;--j){
				if(vis[j]){
					d=j;
					break;
				}
			}
			if(!d)Write(-INF);
			else Write(rank[d]);
			putchar('\n');
		}
		if(done[i].type==4){
			int d=0;
			for(int j=done[i].rank+1;j<=n;++j){
				if(vis[j]){
					d=j;
					break;
				}
			}
			if(!d)Write(INF);
			else Write(rank[d]);
			putchar('\n');	
		}
		if(done[i].type==5){
			vis[done[i].rank]=true;
			maxn=Max(maxn,done[i].rank);
			updata(done[i].rank);
		}
	}
	return 0;
}
2021/8/3 16:56
加载中...