Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define N int(5e4 + 5)
- struct point {
- int x, y, dir, num;
- void read(int a) {
- num = a;
- char c;
- scanf("%d %d %c", &x, &y, &c);
- switch (c) {
- case 'S': dir = 0; break;
- case 'W': dir = 3; break;
- case 'N': dir = 2; break;
- case 'E': dir = 1; break;
- }
- }
- void rot() {
- int nx = -y;
- y = x;
- x = nx;
- dir = (dir + 1) % 4;
- }
- };
- point p[N];
- int res[N];
- bool operator < (point a, point b) {
- if (a.x + a.y == b.x + b.y)
- return (a.y - a.x < b.y - b.x);
- return (a.x + a.y < b.x + b.y);
- }
- struct two {
- int l, r;
- two() {}
- two (int a, int b) {
- l = a, r = b;
- }
- };
- struct treap {
- int x, y, sum, l, r, val;
- treap() {}
- treap(int a, int b, int c) {
- x = a, y = b, sum = c;
- sum = 1;
- l = r = 0;
- val = 1;
- }
- };
- treap t[N];
- int root, num;
- void update(int v) {
- if (!v) return;
- t[v].sum = t[ t[v].l ].sum + t[ t[v].r ].sum + t[v].val;
- }
- int merge(int l, int r) {
- if (!l || !r)
- return l + r;
- if (t[l].y < t[r].y) {
- t[r].l = merge(l, t[r].l);
- update(r);
- return r;
- }
- else {
- t[l].r = merge(t[l].r, r);
- update(l);
- return l;
- }
- }
- two split(int v, int x) {
- if (!v) return two(0, 0);
- if (t[v].x <= x) {
- two res = split(t[v].r, x);
- t[v].r = res.l;
- update(v);
- return two(v, res.r);
- }
- else {
- two res = split(t[v].l, x);
- t[v].l = res.r;
- update(v);
- return two(res.l, v);
- }
- }
- bool find(int v, int x) {
- if (!v) return false;
- if (t[v].x == x) {
- t[v].val++;
- update(v);
- return true;
- }
- if (t[v].x < x) {
- bool ret = find(t[v].r, x);
- update(v);
- return ret;
- }
- else {
- bool ret = find(t[v].l, x);
- update(v);
- return ret;
- }
- }
- void draw(int v, int h) {
- if (!v) return;
- draw(t[v].r, h + 1);
- fprintf(stdout, "%*d/%d\n", 4 * h, t[v].sum, t[v].x);
- draw(t[v].l, h + 1);
- }
- void insert(int x) {
- if (!find(root, x)) {
- two res = split(root, x);
- t[++num] = treap(x, rand() * RAND_MAX + rand(), 0);
- root = merge(res.l, num);
- root = merge(root, res.r);
- }
- }
- int sum(int r) {
- /*cout << "r = " << r << endl;
- draw(root, 0);
- cout << "---------------\n";
- draw(res.l, 0);
- cout << "---------------\n";
- draw(res.r, 0);
- cout << "---------------\n";*/
- two res = split(root, r);
- int mem = t[res.l].sum;
- root = merge(res.l, res.r);
- return mem;
- }
- int main() {
- freopen("sentinels.in", "r", stdin);
- freopen("sentinels.out", "w", stdout);
- int n;
- scanf("%d ", &n);
- for(int i = 0; i < n; i++)
- p[i].read(i);
- for (int i = 0; i < 4; i++) {
- root = 0;
- num = 0;
- sort(p, p + n);
- /* for (int j = 0; j < n; j++) {
- cout << p[j].x << " " << p[j].y << " -> " << p[j].dir << endl;
- }
- cout << endl;*/
- for (int j = 0; j < n; j++) {
- if (p[j].dir == 0) {
- res[ p[j].num ] = sum(p[j].y - p[j].x);
- }
- insert(p[j].y - p[j].x);
- //draw(root, 0);
- //cout << "---------------\n";
- }
- for (int j = 0; j < n; j++)
- p[j].rot();
- }
- for (int i = 0; i < n; i++)
- cout << res[i] << "\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement