• 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
    ", 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
    ", lst);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    I.MX6 Surfaceflinger 机制
    理解 Android Fragment
    RPi 2B DDNS 动态域名
    RPi 2B IPC webcam server
    理解 Android MVP 开发模式
    I.MX6 system.img unpack repack
    can't set android permissions
    VMware Ubuntu 共享文件夹
    解决oracle数据库连接不上的问题
    perfect-scrollbar示例
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2683.html
Copyright © 2020-2023  润新知