hdu 5249 KPI 权值线段树裸题

#include <bits/stdc++.h>
using namespace std;
const int base = 200020;
const int maxn = 400020;
struct	T {
	int l,r,num,lazy;
} t[maxn*4]; // t[p] 表示值遇 l 到 r,num是该数出现次数
char s[10];
int minn,add;
void build(int p,int l,int r) {
	t[p].l = l;
	t[p].r = r;
	t[p].num = 0;
	t[p].lazy = 0;
	if(t[p].l==t[p].r) return ;
	int mid = (l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}
void lazy(int p) {
	if(t[p].lazy==0)return ;
	else {
		t[p].lazy = 0; 
		t[p*2].lazy = 1;
		t[p*2].num = 0;
		t[p*2+1].lazy = 1;
		t[p*2+1].num = 0;
	}
}
void insert(int p,int v,int x) {
	if(t[p].l==t[p].r) {
		if(t[p].l==x) {
			t[p].num+=v;//插入就是出现次数++,删除就是--
		}
		return ;
	}
	lazy(p);
	int mid = (t[p].l+t[p].r)>>1;
	if(x<=mid)insert(p*2,v,x);
	else insert(p*2+1,v,x);
	t[p].num = t[p*2].num + t[p*2+1].num;
}

void update(int p,int x) { //工资低于x离开
	if(t[p].r<x) {
		t[p].num = 0;
		t[p].lazy = 1;
		return ;
	}
	if(t[p].l==t[p].r) {
		if(t[p].r<x)t[p].num = 0;
		return ;
	}
	lazy(p);
	int mid = (t[p].l+t[p].r)>>1;
	if(x<=mid) {
		update(p*2,x);
	} else {
		update(p*2,x);
		update(p*2+1,x);
	}
	t[p].num = t[p*2].num + t[p*2+1].num;
}
int ask(int p,int k) { //查询全局第 k 小,第 n - k + 1 大
//查询n - k + 1小则为查询第k大
	if(t[p].l==t[p].r)return t[p].l;
	lazy(p);
	if(k<=t[2*p].num)ask(p*2,k);
	else ask(p*2+1,k-t[p*2].num);
}
int main() {
	int kk,x,sum = 0;
	int cnt = 1;
	while(scanf("%d",&kk)>0) {
		queue<int> q;	while(!q.empty())q.pop();
		build(1,0,400100);
		printf("Case #%d:\n",cnt);cnt++;
		
		for(int i=0; i<kk; i++) {
			scanf("%s",s);
			if(s[0]=='i'){
				scanf("%d",&x);
				insert(1,1,x);
				q.push(x);
			}else if(s[0]=='o'){
				if(q.empty())continue;
				int x = q.front(); q.pop();
				insert(1,-1,x);
			}else {
				printf("%d\n",ask(1,t[1].num/2+1));
			} 
		}
	}


	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41603898/article/details/94590493
今日推荐