bzoj2683/4066 简单题

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2683

http://www.lydsy.com/JudgeOnline/problem.php?id=4066

【题解】

学习了一发kdtree

感觉十分神奇

用一个类似于平衡树的来维护平面。

然后由于可能出现复杂度退化,大约10000个点就重构一次。

我这么傻逼把nth_element(...)的t+l打成t+1也是没谁了。。。

upd: 5/5又写了一遍怎么又达成+1了啊。。。。。。。

nth_element(t+l, t+mid, t+r+1);

2683:

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + 10;
const int mod = 1e9+7;

# define FO_OPEN 0
# define RG register
# define ST static

inline void gmin(int &x, int y) {if(x > y) x = y;}
inline void gmax(int &x, int y) {if(x < y) x = y;}

inline bool in(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
    return x1 <= xx1 && xx2 <= x2 && y1 <= yy1 && yy2 <= y2;    
}

inline bool out(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
    return x1 > xx2 || x2 < xx1 || y1 > yy2 || y2 < yy1;
}

int D;
struct node {
    int d[2], mi[2], mx[2], l, r;
    ll v, s;
    friend bool operator == (node a, node b) {
        return a.d[0] == b.d[0] && a.d[1] == b.d[1];
    }
    friend bool operator < (node a, node b) {
        return a.d[D] < b.d[D];
    }
}t[M];

# define ls T[x].l
# define rs T[x].r

struct KDT {
    node T[M], tmp;
    int siz, rt;
    inline void set() {
        siz = rt = 0;
    }
    inline void up(int x) {
        for (int i=0; i<2; ++i) {
            T[x].mx[i] = T[x].mi[i] = T[x].d[i];
            if(ls) gmin(T[x].mi[i], T[ls].mi[i]);
            if(rs) gmin(T[x].mi[i], T[rs].mi[i]);
            if(ls) gmax(T[x].mx[i], T[ls].mx[i]);
            if(rs) gmax(T[x].mx[i], T[rs].mx[i]);
        }
        T[x].s = T[x].v + T[ls].s + T[rs].s;
    }
    inline void insert(int &x, int d) {
        if(!x) {
            x = ++siz;
            T[x].d[0] = T[x].mi[0] = T[x].mx[0] = tmp.d[0];
            T[x].d[1] = T[x].mi[1] = T[x].mx[1] = tmp.d[1];
        }
        if(T[x] == tmp) {
            T[x].v += tmp.v;
            T[x].s += tmp.v;
            return ;
        }
        if(tmp.d[d] < T[x].d[d]) insert(ls, d^1);
        else insert(rs, d^1);
        up(x);
    } 
    inline ll query(int x, int x1, int y1, int x2, int y2) {
        if(!x) return 0;
        ll ret = 0;
        if(in(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return T[x].s;
        if(out(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return 0;
        if(in(x1, y1, x2, y2, T[x].d[0], T[x].d[1], T[x].d[0], T[x].d[1])) ret += T[x].v;
        return query(ls, x1, y1, x2, y2) + query(rs, x1, y1, x2, y2) + ret;
    }
    inline int rebuild(int l, int r, int d) {
        if(l>r) return 0;
        int mid = l+r>>1;
        D = d; nth_element(t+l, t+mid, t+r+1);
        T[mid] = t[mid];
        T[mid].l = rebuild(l, mid-1, d^1);
        T[mid].r = rebuild(mid+1, r, d^1);
        up(mid);
        return mid;
    }
}T;

# undef ls
# undef rs

int REBUILD_SIZE = 5000;

int main() {
    scanf("%*d"); T.set();
    int opt, x1, y1, x2, y2;
    while(1) {
        scanf("%d", &opt); if(opt == 3) break;
        if(opt == 1) {
            scanf("%d%d%d", &x1, &y1, &x2);
            T.tmp.d[0] = T.tmp.mx[0] = T.tmp.mi[0] = x1;
            T.tmp.d[1] = T.tmp.mx[1] = T.tmp.mi[1] = y1;
            T.tmp.v = x2, T.tmp.s = x2;
            T.insert(T.rt, 0);
            if(T.siz == REBUILD_SIZE) {
                for (int i=1; i<=T.siz; ++i) t[i] = T.T[i];
                T.rt = T.rebuild(1, T.siz, 0);
                REBUILD_SIZE += 5000;
            }
        }
        if(opt == 2) {
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            printf("%lld\n", T.query(T.rt, x1, y1, x2, y2));
        }
    }
    return 0;
}
View Code

4066:

# include <cctype>
# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

inline ll read() {
    ll x = 0, f = 1; char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = x*10+ch-'0';
        ch = getchar();
    }
    return x*f;
}

inline void gmax(int &x, int y) {
    if(x < y) x = y;
}
inline void gmin(int &x, int y) {
    if(x > y) x = y;
}

inline bool in(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
    return x1 <= xx1 && xx2 <= x2 && y1 <= yy1 && yy2 <= y2;    
}

inline bool out(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
    return x1 > xx2 || x2 < xx1 || y1 > yy2 || y2 < yy1;
}


int D;
struct node {
    int d[2], mx[2], mi[2], l, r;
    ll v, s;
    friend bool operator == (node a, node b) {
        return a.d[0] == b.d[0] && a.d[1] == b.d[1];
    }
    friend bool operator < (node a, node b) {
        return a.d[D] < b.d[D];
    }
}t[M];

# define ls T[x].l
# define rs T[x].r

node tmp;
struct KDTree {
    node T[M];
    int rt, siz;
    inline void set() {
        siz = 0; rt = 0;
    }
    inline void up(int x) {
        for (int i=0; i<2; ++i) {
            T[x].mi[i] = T[x].mx[i] = T[x].d[i];
            if(ls) gmin(T[x].mi[i], T[ls].mi[i]);
            if(rs) gmin(T[x].mi[i], T[rs].mi[i]);
            if(ls) gmax(T[x].mx[i], T[ls].mx[i]);
            if(rs) gmax(T[x].mx[i], T[rs].mx[i]);
        }
        T[x].s = T[x].v + T[ls].s + T[rs].s;
    }
    inline void insert(int &x, int d) {
        if(!x) {
            x = ++siz;
            T[x].d[0] = T[x].mi[0] = T[x].mx[0] = tmp.d[0];
            T[x].d[1] = T[x].mi[1] = T[x].mx[1] = tmp.d[1];
        }
        if(tmp == T[x]) {
            T[x].v += tmp.v;
            T[x].s += tmp.v;
            return ;
        }
        if(tmp.d[d] < T[x].d[d]) insert(ls, d^1);
        else insert(rs, d^1);
        up(x);
    }
    inline ll query(int x, int x1, int y1, int x2, int y2) {
        if(!x) return 0ll;
        ll ret = 0;
        if(in(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return T[x].s;
        if(out(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return 0ll;
        if(in(x1, y1, x2, y2, T[x].d[0], T[x].d[1], T[x].d[0], T[x].d[1])) ret += T[x].v;
        ret += query(ls, x1, y1, x2, y2) + query(rs, x1, y1, x2, y2);
        return ret;
    }
    inline int rebuild(int l, int r, int d) {
        if(l>r) return 0;
        int mid = l+r>>1; D = d;
        nth_element(t+l, t+mid, t+r+1);
        T[mid] = t[mid];
        T[mid].l = rebuild(l, mid-1, d^1);
        T[mid].r = rebuild(mid+1, r, d^1);
        up(mid);
        return mid;
    }
}T;

# undef ls
# undef rs

int REBUILD_SIZE = 10000;

int main() {
    int opt, x1, y1, x2, y2;
    T.set();
    ll lst = 0;
    scanf("%*d");
    while(1) {
        opt = read();if(opt == 3) break;
        if(opt == 1) {
            x1 = read() ^ lst, y1 = read() ^ lst, x2 = read() ^ lst;
            tmp.d[0] = x1, tmp.d[1] = y1, tmp.v = tmp.s = x2;
            T.insert(T.rt, 0);
            if(T.siz == REBUILD_SIZE) {
                for (int i=1; i<=T.siz; ++i) t[i] = T.T[i];
                T.rt = T.rebuild(1, T.siz, 0); 
                REBUILD_SIZE += 10000;
            }
        }
        if(opt == 2) {
            x1 = read() ^ lst, y1 = read() ^ lst, x2 = read() ^ lst, y2 = read() ^ lst;
            lst = T.query(T.rt, x1, y1, x2, y2);
            printf("%lld\n", lst);
        }
    }
    return 0;
}
View Code

 

posted @ 2017-05-04 23:24  Galaxies  阅读(141)  评论(0编辑  收藏  举报