zoukankan      html  css  js  c++  java
  • CDQ分治

    学习链接

    OI Wiki

    UntilDawn知乎

    BZOJ1935 园丁的烦恼

    思路

    对于每个查询查分成四个分别进行计数。三维分别为时间、(x)(y),分治时间,归并(x),树状数组(y)

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 500000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    const int MX = 10000007;
    
    int n, q, tot;
    int ans[maxn], tree[MX];
    int x, y, xx, yy;
    
    struct node {
        int op, x, y, c, qid;
    }a[maxn*5];
    
    void add(int x, int val) {
        while(x < MX) {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    bool cmp(node a, node b) {
        return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    
    void CDQ(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        CDQ(l, mid); CDQ(mid + 1, r);
        int ls = l;
        for(int rs = mid + 1; rs <= r; ++rs) {
            if(a[rs].op == 2) {
                for( ; ls <= mid && a[ls].x <= a[rs].x; ++ls) {
                    if(a[ls].op == 1) add(a[ls].y, a[ls].c);
                }
                ans[a[rs].qid] += a[rs].c * ask(a[rs].y);
            }
        }
        --ls;
        while(ls >= l) {
            if(a[ls].op == 1) add(a[ls].y, -1);
            --ls;
        }
        inplace_merge(a + l, a + mid + 1, a + r + 1, cmp);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d%d", &n, &q);
        for(int i = 1; i <= n; ++i) {
            scanf("%d%d", &x, &y);
            ++x, ++y;
            a[++tot] = {1, x, y, 1, 0};
        }
        for(int i = 1; i <= q; ++i) {
            scanf("%d%d%d%d", &x, &y, &xx, &yy);
            ++x, ++y, ++xx, ++yy;
            a[++tot] = {2, xx, yy, 1, i};
            a[++tot] = {2, x - 1, yy, -1, i};
            a[++tot] = {2, xx, y - 1, -1, i};
            a[++tot] = {2, x - 1, y - 1, 1, i};
        }
        CDQ(1, tot);
        for(int i = 1; i <= q; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
    

    BZOJ1176 Mokia

    思路

    在上面的基础上改成了动态加点,但是处理方式其实是一样的,题目里面的(s)是没有用的。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 2000000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int w, tot, id, op, x, y, xx, yy, val;
    int tree[maxn], ans[maxn];
    struct node {
        int x, y, op, c, id;
        bool operator < (const node& a) const {
            return x == a.x ? y < a.y : x < a.x;
        }
    }a[maxn];
    
    void add(int x, int val) {
        while(x <= w) {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void cdq(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq(l, mid), cdq(mid + 1, r);
        int ls = l, rs = mid + 1;
        for( ; rs <= r; ++rs) {
            if(a[rs].op == 2) {
                for( ; ls <= mid && a[ls].x <= a[rs].x; ++ls) {
                    if(a[ls].op == 1) add(a[ls].y, a[ls].c);
                }
                ans[a[rs].id] += a[rs].c * ask(a[rs].y);
            }
        }
        --ls;
        while(ls >= l) {
            if(a[ls].op == 1) add(a[ls].y, -a[ls].c);
            --ls;
        }
        inplace_merge(a + l, a + mid + 1, a + r + 1);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%*d%d", &w);
        while(1) {
            scanf("%d", &op);
            if(op == 3) break;
            if(op == 1) {
                scanf("%d%d%d", &x, &y, &val);
                a[++tot] = {x, y, 1, val, 0};
            } else {
                scanf("%d%d%d%d", &x, &y, &xx, &yy);
                ++id;
                a[++tot] = {x - 1, y - 1, 2, 1, id};
                a[++tot] = {x - 1, yy, 2, -1, id};
                a[++tot] = {xx, y - 1, 2, -1, id};
                a[++tot] = {xx, yy, 2, 1, id};
            }
        }
        cdq(1, tot);
        for(int i = 1; i <= id; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
    

    陌上花开

    思路

    三维偏序,在进行(cdq)分治之前需要将相同的进行合并,最后对于相同的花(假设是(v)),那么对于(v)的等级要加上(cnt[v]-1)。三维分别为(a,b,c),分治(a),归并(b),树状数组(c)

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 200000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, k, tot;
    int tree[maxn], ans[maxn];
    
    struct node {
        int a, b, c, cnt, ans;
    }tmp[maxn], num[maxn];
    
    bool cmp1(node x, node y) {
        return x.a != y.a ? x.a < y.a : x.b != y.b ? x.b < y.b : x.c < y.c;
    }
    
    bool cmp2(node x, node y) {
        return x.b != y.b ? x.b < y.b : x.c < y.c;
    }
    
    void add(int x, int val) {
        while(x <= k) {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void cdq(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq(l, mid), cdq(mid + 1, r);
        int ls = l, rs = mid + 1;
        while(ls <= mid && rs <= r) {
            if(num[ls].b <= num[rs].b) {
                add(num[ls].c, num[ls].cnt);
                ++ls;
            } else {
                num[rs].ans += ask(num[rs].c);
                ++rs;
            }
        }
        while(rs <= r) {
            num[rs].ans += ask(num[rs].c);
            ++rs;
        }
        --ls;
        while(ls >= l) {
            add(num[ls].c, -num[ls].cnt);
            --ls;
        }
        inplace_merge(num + l, num + mid + 1, num + r + 1, cmp2);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; ++i) {
            scanf("%d%d%d", &tmp[i].a, &tmp[i].b, &tmp[i].c);
        }
        sort(tmp + 1, tmp + n + 1, cmp1);
        num[++tot] = tmp[1];
        num[tot].cnt = 1;
        num[tot].ans = 0;
        for(int i = 2; i <= n; ++i) {
            if(tmp[i].a == num[tot].a && tmp[i].b == num[tot].b && tmp[i].c == num[tot].c) {
                ++num[tot].cnt, num[tot].ans = 0;
            } else {
                num[++tot] = tmp[i];
                num[tot].cnt = 1;
                num[tot].ans = 0;
            }
        }
        cdq(1, tot);
        for(int i = 1; i <= tot; ++i) {
            ans[num[i].cnt-1+num[i].ans] += num[i].cnt;
        }
        for(int i = 0; i < n; ++i) {
            printf("%d
    ", ans[i]);
        }
        return 0;
    }
    

    BZOJ3295 动态逆序对

    思路

    我们先跑出原序列的逆序对,然后用(cdq)来计算出删除这个数逆序对的变化值,三维分别为时间、位置、值,分治时间,归并位置,树状数组值。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 100000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, m, x, tot;
    LL sum;
    int num[maxn], tree[maxn], vis[maxn];
    LL ans[maxn];
    
    struct node {
        int x, tim;
    }a[maxn], tmp[maxn];
    
    void add(int x, int val, int n) {
        while(x <= n) {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void cdq(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq(l, mid), cdq(mid + 1, r);
        int cnt = 0, ls = mid, rs = r;
        for(; rs >= mid + 1; --rs) {
            for(; ls >= l && a[ls].x > a[rs].x; --ls) {
                add(a[ls].tim, 1, m + 1);
                ++cnt;
            }
            if(a[rs].tim != m + 1) ans[a[rs].tim] += cnt - ask(a[rs].tim);
        }
        ++ls;
        while(ls <= mid) {
            add(a[ls].tim, -1, m + 1);
            ++ls;
        }
        cnt = 0, ls = l, rs = mid + 1;
        for(; ls <= mid; ++ls) {
            for(; rs <= r && a[rs].x < a[ls].x; ++rs) {
                add(a[rs].tim, 1, m + 1);
                ++cnt;
            }
            if(a[ls].tim != m + 1) ans[a[ls].tim] += cnt - ask(a[ls].tim);
        }
        --rs;
        while(rs >= mid + 1) {
            add(a[rs].tim, -1, m + 1);
            --rs;
        }
        cnt = ls = l, rs = mid + 1;
        while(ls <= mid && rs <= r) {
            if(a[ls].x < a[rs].x) {
                tmp[cnt++] = a[ls++];
            } else {
                tmp[cnt++] = a[rs++];
            }
        }
        while(ls <= mid) {
            tmp[cnt++] = a[ls++];
        }
        while(rs <= r) {
            tmp[cnt++] = a[rs++];
        }
        for(int i = l; i <= r; ++i) a[i] = tmp[i];
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &num[i]);
            a[++tot] = {num[i], m + 1};
            vis[num[i]] = tot;
        }
        for(int i = 1; i <= m; ++i) {
            scanf("%d", &x);
            a[vis[x]].tim = i;
        }
        for(int i = 1; i <= n; ++i) {
            sum += i - 1 - ask(num[i]);
            add(num[i], 1, n);
        }
        for(int i = 1; i <= n; ++i) {
            add(num[i], -1, n);
        }
        cdq(1, n);
        for(int i = 1; i <= m; ++i) {
            printf("%lld
    ", sum);
            sum -= ans[i];
        }
        return 0;
    }
    

    HDU5324 Boring Class

    思路

    三维分别是位置、(L)(R),分治位置,归并(R),树状数组(L)

    由于需要输出字典序最小的方案,因此我们考虑在合并的时候用右边来更新左边的信息,记录每个位置作为(v_1)能选出的最大的(m)

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 50000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, sz;
    vector<int> vec;
    int L[maxn], R[maxn], tree[maxn], ans[maxn];
    
    struct node {
        int pos, x, y;
        bool operator < (const node& a) const {
            return y > a.y;
        }
    }a[maxn];
    
    void add(int x, int val) {
        while(x <= sz) {
            tree[x] = max(tree[x], val);
            x += lowbit(x);
        }
    }
    
    void del(int x) {
        while(x <= sz) {
            tree[x] = 0;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans = max(ans, tree[x]);
            x -= lowbit(x);
        }
        return ans;
    }
    
    bool cmp(node a, node b) {
        return a.pos < b.pos;
    }
    
    void cdq(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq(mid + 1, r);
        sort(a + l, a + mid + 1);
        sort(a + mid + 1, a + r + 1);
        int ls = l, rs = mid + 1;
        for(; ls <= mid; ++ls) {
            for(; rs <= r && a[rs].y >= a[ls].y; ++rs) {
                add(a[rs].x, ans[a[rs].pos]);
            }
            ans[a[ls].pos] = max(ans[a[ls].pos], ask(a[ls].x) + 1);
        }
        --rs;
        while(rs >= l) {
            del(a[rs].x);
            --rs;
        }
        sort(a + l, a + mid + 1, cmp);
        cdq(l, mid);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        while(~scanf("%d", &n)) {
            vec.clear();
            for(int i = 1; i <= n; ++i) scanf("%d", &L[i]), a[i].x = L[i], a[i].pos = i, vec.emplace_back(L[i]);
            for(int i = 1; i <= n; ++i) scanf("%d", &R[i]), a[i].y = R[i], ans[i] = 1;
            sort(vec.begin(), vec.end());
            vec.erase(unique(vec.begin(), vec.end()), vec.end());
            for(int i = 1; i <= n; ++i) a[i].x = lower_bound(vec.begin(), vec.end(), a[i].x) - vec.begin() + 1;
            sz = vec.size();
            cdq(1, n);
            int mx = 0, idx = 1;
            for(int i = 1; i <= n; ++i) {
                if(ans[i] > mx) {
                    mx = ans[i];
                    idx = i;
                }
            }
            int las = L[idx], lst = R[idx];
            vec.clear();
            vec.emplace_back(idx);
            for(int i = idx + 1; i <= n; ++i) {
                if(ans[i] == mx - 1 && L[i] <= las && R[i] >= lst) {
                    mx = ans[i], las = L[i], lst = R[i];
                    vec.emplace_back(i);
                }
            }
            printf("%d
    ", (int)vec.size());
            for(int i = 0; i < (int)vec.size(); ++i) {
                if(i) printf(" ");
                printf("%d", vec[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    

    HDU5126 stars

    思路

    四维偏序,分别为时间,(x,y,z),分治时间和(x),归并(x,y),树状数组(z)

    注意第二个(cdq)不能改变第一个的数组位置,在第一个(cdq)时需要标记每个数组在该分治中是左边一半还是右边一半,如果不标记的话那么在第二次(cdq)时就会忽略时间的关系。

    代码

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 450000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    vector<int> vec;
    int t, q, tot, op, x, y, z, xx, yy, zz, sz;
    int tree[maxn], ans[maxn];
    
    struct node {
        int x, y, z, op, id, flag, c;
    }a[maxn], tmp[maxn], pp[maxn];
    
    void add(int x, int val) {
        while(x <= sz) {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    
    int ask(int x) {
        int ans = 0;
        while(x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void cdq2(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq2(l, mid), cdq2(mid + 1, r);
        int ls = l, rs = mid + 1, cnt = l;
        for(; rs <= r; ++rs) {
            for(; ls <= mid && tmp[ls].y <= tmp[rs].y; ++ls) {
                if(tmp[ls].op == 1 && tmp[ls].flag) add(tmp[ls].z, tmp[ls].c);
            }
            if(tmp[rs].op == 2 && !tmp[rs].flag) ans[tmp[rs].id] += tmp[rs].c * ask(tmp[rs].z);
        }
        --ls;
        while(ls >= l) {
            if(tmp[ls].op == 1 && tmp[ls].flag) add(tmp[ls].z, -tmp[ls].c);
            --ls;
        }
        ls = l, rs = mid + 1;
        while(ls <= mid && rs <= r) {
            if(tmp[ls].y < tmp[rs].y) {
                pp[cnt++] = tmp[ls++];
            } else if(tmp[ls].y > tmp[rs].y) {
                pp[cnt++] = tmp[rs++];
            } else if(tmp[ls].z <= tmp[rs].z) {
                pp[cnt++] = tmp[ls++];
            } else {
                pp[cnt++] = tmp[rs++];
            }
        }
        while(ls <= mid) {
            pp[cnt++] = tmp[ls++];
        }
        while(rs <= r) {
            pp[cnt++] = tmp[rs++];
        }
        for(int i = l; i <= r; ++i) tmp[i] = pp[i];
    }
    
    void cdq1(int l, int r) {
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq1(l, mid); cdq1(mid + 1, r);
        int ls = l, rs = mid + 1, cnt = l;
        while(ls <= mid && rs <= r) {
            if(a[ls].x < a[rs].x) {
                tmp[cnt] = a[ls++];
                tmp[cnt++].flag = 1;
            } else if(a[ls].x > a[rs].x) {
                tmp[cnt] = a[rs++];
                tmp[cnt++].flag = 0;
            } else if(a[ls].y < a[rs].y) {
                tmp[cnt] = a[ls++];
                tmp[cnt++].flag = 1;
            } else if(a[ls].y > a[rs].y) {
                tmp[cnt] = a[rs++];
                tmp[cnt++].flag = 0;
            } else if(a[ls].z <= a[rs].z) {
                tmp[cnt] = a[ls++];
                tmp[cnt++].flag = 1;
            } else {
                tmp[cnt] = a[rs++];
                tmp[cnt++].flag = 0;
            }
        }
        while(ls <= mid) {
            tmp[cnt] = a[ls++];
            tmp[cnt++].flag = 1;
        }
        while(rs <= r) {
            tmp[cnt] = a[rs++];
            tmp[cnt++].flag = 0;
        }
        for(int i = l; i <= r; ++i) a[i] = tmp[i];
        cdq2(l, r);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        FIN;
    #endif
        scanf("%d", &t);
        while(t--) {
            tot = 0;
            vec.clear();
            scanf("%d", &q);
            int cnt = 0;
            for(int i = 1; i <= q; ++i) {
                scanf("%d%d%d%d", &op, &x, &y, &z);
                if(op == 1) a[++tot] = {x, y, z, op, 0, 0, 1}, vec.push_back(z);
                else {
                    scanf("%d%d%d", &xx, &yy, &zz);
                    ++cnt;
                    a[++tot] = {xx, yy, zz, op, cnt, 0, 1};
                    a[++tot] = {x - 1, yy, zz, op, cnt, 0, -1};
                    a[++tot] = {xx, y - 1, zz, op, cnt, 0, -1};
                    a[++tot] = {xx, yy, z - 1, op, cnt, 0, -1};
                    a[++tot] = {x - 1, y - 1, zz, op, cnt, 0, 1};
                    a[++tot] = {x - 1, yy, z - 1, op, cnt, 0, 1};
                    a[++tot] = {xx, y - 1, z - 1, op, cnt, 0, 1};
                    a[++tot] = {x - 1, y - 1, z - 1, op, cnt, 0, -1};
                    vec.push_back(z); vec.push_back(z - 1);
                    vec.push_back(zz); vec.push_back(zz - 1);
                }
            }
            sort(vec.begin(), vec.end());
            vec.erase(unique(vec.begin(), vec.end()), vec.end());
            sz = vec.size();
            for(int i = 1; i <= tot; ++i) {
                a[i].z = lower_bound(vec.begin(), vec.end(), a[i].z) - vec.begin() + 1;
            }
            cdq1(1, tot);
            for(int i = 1; i <= cnt; ++i) {
                printf("%d
    ", ans[i]);
                ans[i] = 0;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    PostgreSQL 10编译安装(CentOS 7)
    CentOS安装单机Zookeeper
    [Oracle报错]TNS-12535: TNS:operation timed out、TNS-00505: Operation timed out
    hibernate一级缓存及对象的状态
    hibernate框架的简单入门
    Json和Ajax
    sql多行多列重复
    折线图饼状图柱形图
    XML文件的读取
    Json数据产生树形结构
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11323992.html
Copyright © 2011-2022 走看看