您的位置:首页 > 其它

CF 19D, 线段树套set/KD-tree

2016-07-28 21:40 471 查看
题目大意:有n个操作,要么在平面上增删一个点,要么询问某个坐标右上侧(严格大于等于)第一个点是谁(x相同取y最小)。

解:非常智障看错题了,没看到要在右上,所以写了个树套set,发现看错题嘀咕了一下艹这询问set搞不来,想了一下似乎kd-tree可以做,就写了棵,常数卡得很死过了。后来看题解还真是树套set。离散化后每个线段都是一个set,然后插入删除的时候沿途把set搞一下,询问的时候用个小技巧就行了,还是很简单的。

#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <complex>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <deque>
#include <ctime>

using namespace std;

const double EPS = 1e-8;

#define ABS(x) ((x)<0?(-(x)):(x))
#define SQR(x) ((x)*(x))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))

#define LSON(x) ((x)<<1)
#define RSON(x) (((x)<<1)+1)
#define LOWBIT(x) ((x)&(-(x)))
#define MAXS 1111
#define MAXN 222222
#define VOIDPOINT 0
#define LL long long
#define OO 214748364
#define INF 0x3f3f3f3f
#define MP(x,y) make_pair(x,y)

int index;

struct node{
int xy[2];
node(int a = 0, int b = 0) {
xy[0] = a; xy[1] = b;
}
bool operator < (const node &rhs) const {
if (xy[index] == rhs.xy[index]) return xy[index^1] < rhs.xy[index^1];
return xy[index] < rhs.xy[index];
}
};

char str[111];

struct ask{
int type, x, y;
void read() {
scanf("%s %d %d", str, &x, &y);
type = str[0] == 'a' ? 0 : (str[0] == 'r' ? 1 : 2);
}
} q[MAXN];

vector<pair<int, int > >lsh;
node b[MAXN];

struct KDTREE{
int lson[MAXN*4], rson[MAXN*4], size[MAXN*4], alive[MAXN*4];
int minx[MAXN*4], maxx[MAXN*4], miny[MAXN*4], maxy[MAXN*4];
node a[MAXN*4];
int gx, gy, gz;
void setting(int a = 0, int b = 0, int c = 0) {
gx = a; gy = b; gz = c;
}
void build(int kok, int l, int r, int dep) {
if (l > r) return ;

alive[kok] = size[kok] = 0;
int mid = (l + r) >> 1;
index = dep & 1;

nth_element(b + l, b + mid, b + r + 1);
a[kok] = b[mid];
//        cout << kok << ' ' << a[kok].xy[0] <<' '<< a[kok].xy[1] << endl;

build(LSON(kok), l, mid-1, dep+1);
build(RSON(kok), mid+1, r, dep+1);
}
void insert(int kok = 1, int dep = 0) {
////cout << kok << ' '<< a[kok].xy[0] <<' '<< a[kok].xy[1] << endl;
while (1) {
size[kok] += gz;
if (gx == a[kok].xy[0] && gy == a[kok].xy[1]) {
alive[kok] += gz;
return ;
}
index = dep & 1;
++dep;
if (node(gx, gy) < a[kok]) kok = LSON(kok);//insert(LSON(kok), dep + 1);
else kok = RSON(kok); //insert(RSON(kok), dep + 1);
}
//size[kok] = size[LSON(kok)] + alive[kok] + size[RSON(kok)];
}
pair<int, int > query(int kok = 1, int dep = 0) {
if (size[kok] == 0) return MP(INF, INF);
index = dep & 1;
//        cout << kok << ' '<< a[kok].xy[0] <<' '<< a[kok].xy[1] << endl;
pair<int ,int > ans = MP(INF, INF);
if (index == 1) { //node(gx, gy) < a[kok] || gy == a[kok].xy[1] ? : MP(INF, INF)
if (size[RSON(kok)]) ans = query(RSON(kok), dep+1);
if (gy <= a[kok].xy[1] && size[LSON(kok)]) ans = min(ans, query(LSON(kok), dep+1));
if (alive[kok] && gx < a[kok].xy[0] && gy < a[kok].xy[1]) ans = min(ans, MP(a[kok].xy[0], a[kok].xy[1]));
return ans;
}
if (gx < a[kok].xy[0]) {
if (alive[kok] && gy < a[kok].xy[1]) ans = MP(a[kok].xy[0], a[kok].xy[1]);
if (size[LSON(kok)]) ans = min(ans, query(LSON(kok), dep+1));
}
if (ans.first == INF) {
if (size[RSON(kok)]) ans = query(RSON(kok), dep + 1);
}
//!!
return ans;
}
} Tree;

int n;

void init() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
q[i].read();
lsh.push_back(MP(q[i].x, q[i].y));
}
sort(lsh.begin(), lsh.end());
lsh.erase(unique(lsh.begin(), lsh.end()), lsh.end());
for (int i = 0; i < lsh.size(); ++i) b[i] = node(lsh[i].first, lsh[i].second);
Tree.build(1, 0, lsh.size()-1, 0);
}

void solve() {
for (int tt = 0; tt < n; ++tt) {
if (q[tt].type == 0) {
//cout << q[tt].x << ' ' << q[tt].y << endl;
Tree.setting(q[tt].x, q[tt].y, 1);
Tree.insert();
} else if (q[tt].type == 1) {
Tree.setting(q[tt].x, q[tt].y, -1);
Tree.insert();
} else {
Tree.setting(q[tt].x, q[tt].y);
pair<int, int > ans = Tree.query();
if (ans.first == INF) puts("-1");
else printf("%d %d\n", ans.first, ans.second);
}
}
}

int main() {
//    freopen("test.txt", "r", stdin);
init();
solve();
return 0;
}


CF 19D
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: