zoukankan      html  css  js  c++  java
  • BZOJ 1176 Mokia

    CDQ分治

    求矩形面积可以看成类似二位前缀和的加减

    这样就可以把题目看成x,y,t的三维偏序问题,直接上CDQ分治。

    这里不用去重,但是我们在排序的时候一定要把三个维度相同的询问放在修改后面,因为CDQ每次分治都是计算左边对右边的贡献。

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define full(a, b) memset(a, b, sizeof a)
    #define __fastIn ios::sync_with_stdio(false), cin.tie(0)
    #define pb push_back
    using namespace std;
    using LL = long long;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int ret = 0, w = 0; char ch = 0;
        while(!isdigit(ch)){
            w |= ch == '-', ch = getchar();
        }
        while(isdigit(ch)){
            ret = (ret << 3) + (ret << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -ret : ret;
    }
    template <typename A>
    inline A __lcm(A a, A b){ return a / __gcd(a, b) * b; }
    template <typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    const int N = 2000005;
    int cur, opt, t, n, cnt, c[N], ans[N];
    struct Query{
        int op, id, x, y, t, val;
        Query(){}
        Query(int x, int y, int t, int val): x(x), y(y), t(t), val(val){
            op = id = 0;
        }
        Query(int op, int id, int x, int y, int t, int val): op(op), id(id), x(x), y(y), t(t), val(val){}
        bool operator < (const Query &rhs) const {
            if(x != rhs.x) return x < rhs.x;
            if(y != rhs.y) return y < rhs.y;
            if(t != rhs.t) return t < rhs.t;
            return val > rhs.val;
        }
    }v[N], aux[N];
    
    inline void add(int k, int val){
        for(; k <= t; k += lowbit(k)) c[k] += val;
    }
    
    inline int query(int k){
        int ret = 0;
        for(; k; k -= lowbit(k)) ret += c[k];
        return ret;
    }
    
    void CDQ(int l, int r){
        if(l == r) return;
        int mid = (l + r) >> 1;
        CDQ(l, mid), CDQ(mid + 1, r);
        for(int i = l; i <= r; i ++){
            aux[i - l] = v[i];
        }
        int i = 0,  j = mid + 1 - l;
        for(int k = l; k <= r; k ++){
            if(i > mid - l){
                if(aux[j].op != 0) ans[aux[j].id] += aux[j].op * query(aux[j].t);
                v[k] = aux[j ++];
            }
            else if(j > r - l){
                if(aux[i].op == 0) add(aux[i].t, aux[i].val);
                v[k] = aux[i ++];
            }
            else if(aux[i].y <= aux[j].y){
                if(aux[i].op == 0) add(aux[i].t, aux[i].val);
                v[k] = aux[i ++];
            }
            else{
                if(aux[j].op != 0) ans[aux[j].id] += aux[j].op * query(aux[j].t);
                v[k] = aux[j ++];
            }
        }
        for(int k = 0; k < mid - l + 1; k ++){
            if(aux[k].op == 0) add(aux[k].t, -aux[k].val);
        }
    }
    
    int main(){
    
        for(;;){
            opt = read();
            if(opt == 3) break;
            else if(opt == 0) n = read() + 1;
            else if(opt == 1){
                int x = read() + 1, y = read() + 1, w = read();
                v[++cur] = Query(x, y, ++ t, w);
            }
            else{
                int x1 = read() + 1, y1 = read() + 1, x2 = read() + 1, y2 = read() + 1;
                cnt ++, t ++;
                v[++cur] = Query(1, cnt, x2, y2, t, 0);
                v[++cur] = Query(-1, cnt, x2, y1 - 1, t, 0);
                v[++cur] = Query(-1, cnt, x1 - 1, y2, t, 0);
                v[++cur] = Query(1, cnt, x1 - 1, y1 - 1, t, 0);
            }
        }
        sort(v + 1, v + cur + 1);
        CDQ(1, cur);
        for(int i = 1; i <= cnt; i ++){
            printf("%d
    ", ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    无法连接到已配置的开发web服务器
    Java开发命名规范总结
    java包名命名规范[【转】
    github远程建了分支,本地看不到的问题
    git远程删除分支后,本地git branch -a 依然能看到的解决办法
    git主要操作命令
    Ant之build.xml配置详解【转】
    git合并指定文件到另一分支
    java最简单实现Log打印和生成日志文件
    SCF: 简单配置门面[转]
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/11395876.html
Copyright © 2011-2022 走看看