CF 19D 线段树+set压缩坐标轴+离散化map

题意:

n个操作,在200000*200000的平面上加删点

find 严格在坐标右上角,x最小,再y最小的点

 

线段树做,区间为离散化后的 X轴坐标 ,维护区间点数 和 最小的 y 值 ( 维护最小y值是重要优化 )

#include <stdio.h>
#include <string.h>
#include <queue>
#include <set>
#include <functional>
#include <map>

#define N 201000
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Mid(x,y) ((x+y)>>1)
#define ll int
using namespace std;
inline ll Max(ll a, ll b){ return a>b?a:b;}
inline ll Min(ll a, ll b){ return a<b?a:b;}

int Point[N];
map<int, int> mymap;

vector<int>G;

struct node{
	int l,r;
	int num;
	int maxy;
}tree[N*4];
set<int> treeset[N];
set<int> ::iterator p;

void build( int l, int r, int id){
	tree[id].l = l,  tree[id].r = r;
	tree[id].num = 0;
	tree[id].maxy = 0;
	if(l==r)return ;
	int mid = Mid(l, r);
	build(l, mid, L(id));
	build(mid+1, r, R(id));
}

void insert(int pos, int id, int data, bool add){// add = true 插入data =false 删除data
	if(tree[id].l == tree[id].r){
		if(add)
				treeset[pos].insert(data);
		
		else 
				treeset[pos].erase(data);
		tree[id].num = treeset[pos].size();
		if(tree[id].num)
		tree[id].maxy = *treeset[pos].rbegin();
		else 
			tree[id].maxy = 0;
		return ;
	}
	int mid = Mid(tree[id].l, tree[id].r);

	if(pos <= mid)insert(pos, L(id), data, add);
	else		  insert(pos, R(id), data, add);

	tree[id].num = tree[L(id)].num + tree[R(id)].num;
	tree[id].maxy =Max( tree[L(id)].maxy , tree[R(id)].maxy);
}

int query(int l, int r, int y, int id){
	if( tree[id].l == tree[id].r ){
		if(tree[id].num){

			p = treeset[ tree[id].l ].upper_bound(y);
			if(p != treeset[ tree[id].l ].end() ){
				printf("%d ", Point[ tree[id].l ]);
				return *p;
			}
		}
		return -1;
	}
	if( l == tree[id].l && tree[id].r == r){
		if(tree[id].num == 0 || tree[id].maxy <= y)
			return -1;
	}
	int mid = Mid(tree[id].l , tree[id].r);
	if(r <= mid) return query(l, r, y, L(id));
	if(mid < l) return query(l, r, y, R(id));

	int treey =query(l, mid, y, L(id));
	if(treey > y) return treey;
	return query(mid+1, r, y, R(id));
}

struct QUE{
	char c;
	int u,v;
}que[N];
set<int> tempset;
void Input(int n){
	int u,v; char s[10];
	tempset.clear();
	mymap.clear();		
	for(int i = 1; i <= n; i++){
		scanf("%s %d %d", s, &u, &v);
		que[i].c = s[0], que[i].u = u, que[i].v = v;
		tempset.insert(u);
	}
	p = tempset.begin();
	int size = tempset.size();
	for(int i = 1; i <= size ; i++,p++){
		mymap.insert(pair<int, int>(*p, i));
		Point[i] = *p;
	}
}
int go(int x){
	return mymap.find(x) -> second;
}
int main(){
	int n;
	char s[10];
	while(~scanf("%d",&n)){
		for(int i = 1; i<=200001; i++)treeset[i].clear();
		build(1,200001,1);

		Input(n);

		for(int i = 1; i<=n; i++){
			int u = que[i].u, v = que[i].v;
			if(que[i].c == 'a')				
				insert(go(u),1,v,1);

			else if(que[i].c == 'r')
				insert(go(u),1,v,0);

			else if(que[i].c == 'f')
				printf("%d\n", query(go(u)+1, 200001, v, 1));

		}
	}
	return 0;
}
/* 
7
add 1 1
add 3 4
find 0 0
remove 1 1
find 0 0
add 1 1
find 0 0

ans:
1 1
3 4
1 1

13
add 5 5
add 5 6
add 5 7
add 6 5
add 6 6
add 6 7
add 7 5
add 7 6
add 7 7
find 6 6
remove 7 7
find 6 6
find 4 4

ans:
7 7
-1
5 5

10
add 5 7
add 2 1
add 8 8
add 5 10
add 2 5
find 7 5
find 8 3
find 2 2
find 5 4
find 2 6

ans:
8 8
-1
5 7
8 8
5 7


*/  


 

 

posted on 2013-10-08 22:38  you Richer  阅读(224)  评论(0编辑  收藏  举报