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

    思路:首先我们将问题转换一下,变成问在某个点左下角的权值和,那么每一个询问可以拆成4的这样的询问,然后

    进行CDQ 分治,回溯的时候按x轴排序,然后用树状数组维护y的值。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define x2 skdjflsdg
    #define y2 sdkfjsktge
    
    using namespace std;
    
    const int N = 2e6 + 7;
    const int M = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 +7;
    
    int s, w, cnt, tot, op;
    
    LL ans[M], a[N];
    struct Qus {
        int x, y, idx, id;
    } qus[M], tmp[M];
    
    void modify(int x, int v) {
        for(int i = x; i < N; i += i & -i) {
            a[i] += v;
        }
    }
    
    LL sum(int x) {
        LL ans = 0;
        for(int i = x; i; i -= i & -i) {
            ans += a[i];
        }
        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 p = l, q = mid + 1, cnt = l;
    
        for(int i = mid + 1; i <= r; i++) {
            while(p <= mid && qus[p].x <= qus[i].x) {
                if(qus[p].idx == 0)
                    modify(qus[p].y, qus[p].id);
                p++;
            }
            ans[qus[i].id] += qus[i].idx * sum(qus[i].y);
        }
    
        for(int i = l; i < p; i++) {
            if(qus[i].idx == 0) {
                modify(qus[i].y, -qus[i].id);
            }
        }
    
        p = l, q = mid + 1, cnt = l;
    
        while(p <= mid && q <= r) {
            if(qus[p].x <= qus[q].x) {
                tmp[cnt++] = qus[p++];
            } else {
                tmp[cnt++] = qus[q++];
            }
        }
    
        while(p <= mid) tmp[cnt++] = qus[p++];
        while(q <= r) tmp[cnt++] = qus[q++];
    
        for(int i = l; i <= r; i++) qus[i] = tmp[i];
    
    }
    
    int main() {
        scanf("%d%d", &s, &w);
        while(scanf("%d", &op) && op < 3) {
            if(op == 1) {
                int x, y, a; scanf("%d%d%d", &x, &y, &a);
                x += 2; y += 2;
                qus[++tot].x = x;
                qus[tot].y = y;
                qus[tot].id = a;
                qus[tot].idx = 0;
            } else {
                int x1, y1, x2, y2;
                scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
                x1 += 2, y1 += 2;
                x2 += 2, y2 += 2;
                qus[++tot].x = x2;
                qus[tot].y = y2;
                qus[tot].id = ++cnt;
                qus[tot].idx = 1;
    
                qus[++tot].x = x2;
                qus[tot].y = y1 - 1;
                qus[tot].id = cnt;
                qus[tot].idx = -1;
    
                qus[++tot].x = x1 - 1;
                qus[tot].y = y2;
                qus[tot].id = cnt;
                qus[tot].idx = -1;
    
                qus[++tot].x = x1 - 1;
                qus[tot].y = y1 - 1;
                qus[tot].id = cnt;
                qus[tot].idx = 1;
    
                ans[cnt] = 1ll * (x2 - x1) * (y2 - y1) * s;
            }
        }
        cdq(1, tot);
        for(int i = 1; i <= cnt; i++)
            printf("%lld
    ", ans[i]);
        return 0;
    }
    /*
    */
  • 相关阅读:
    更改Linux时区的两种方法
    Azure上部署FTP服务
    log4j2简单使用
    elasticsearch5.5.2环境搭建
    springTask和Schedule学习
    防止SpringMVC拦截器拦截js等静态资源文件
    Mysql中使用FIND_IN_SET解决IN条件为字符串时只有第一个数据可用的问题
    ServletContext总结
    window.location.href和window.location.replace的区别
    javadoc文档
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9199277.html
Copyright © 2011-2022 走看看