• 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
  • 相关阅读:
    AOP的相关理论介绍
    代码访问数据库时没有报错一直转圈,MySQL不同驱动版本的连接方式
    Linux(CentOS7)设置固定获取IP地址
    NodeJS的安装与配置
    IDEA启动tomcat访问localhost:8080出现404错误
    Win10笔记本电脑外接显示器,如何在笔记本合上的时候让他继续在显示器上使用
    SpringBoot集成Swagger-Bootstrap-UI(已改名为Knife4j)
    Redis学习之Jedis的操作和使用
    SpringBoot整合Swagger2,搭建Restful API在线文档
    IDEA创建SpringBoot项目时出现:Initialization failed for 'https://start.spring.io' Please check URL, network and proxy settings.
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2683.html
Copyright © 2020-2023  润新知