zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    读Hadoop3.2源码,深入了解java调用HDFS的常用操作和HDFS原理
    AI学习笔记:人工智能与机器学习概述
    CDN百科 | 最近,你的APP崩了吗?
    CDN HTTPS安全加速基本概念、解决方案及优化实践
    CDN百科第六讲 | 怎样用CDN抵御攻击?看完这篇漫画你就懂了
    CDN百科第五讲 | CDN和游戏加速器有什么区别?
    CDN百科第四讲 | 如何优雅地在云上“摆摊”——做直播带货,你不得不关注的技术
    CDN百科第三讲 | 如果用了云服务器,还需要做CDN加速吗?
    阿里云杨敬宇:边缘计算行业通识与阿里云ENS的技术演进之路
    CDN百科 | 假如没有CDN,网络世界会变成什么样?
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2683.html
Copyright © 2011-2022 走看看