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





*/  


 

 

你可能感兴趣的:(map)