zoukankan      html  css  js  c++  java
  • 【BZOJ1176】[BOI2007]Mokia 摩基亚

    【BZOJ1176】[BOI2007]Mokia 摩基亚

    题面

    bzoj

    洛谷

    题解

    显然的(CDQ)(/)树套树题

    然而根本不想写树套树,那就用(CDQ)吧。。。

    考虑到点((x1,y1))((x2,y2))区域内既有上限又有下限我们不是很好算

    于是将这个区域的贡献写成另外一种形式,

    ((x,y))((0,0))之间区域的贡献为(S_{(x,y)}),则上面的贡献可表示为

    (S_{(x2,y2)}-S_{(x2,y1-1)}-S_{(y2,x1-1)}+S_{(x1-1,y1-1)})

    分别统计四个贡献就很容易辣

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    namespace IO { 
        const int BUFSIZE = 1 << 20; 
        char ibuf[BUFSIZE], *is = ibuf, *it = ibuf; 
        inline char gc() { 
            if (is == it) it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin); 
    		return *is++; 
        } 
    } 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (ch != '-' && (ch > '9' || ch < '0')) ch = IO::gc();
        if (ch == '-') w = -1 , ch = IO::gc();
        while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = IO::gc();
        return w * data;
    } 
    #define MAX_N 200005 
    #define MAX_W 2000005 
    struct Node { int x, y, id, w; } t[MAX_N << 2]; int ans[MAX_N]; 
    bool cmp_x(Node a, Node b) { return (a.x == b.x) ? (a.y < b.y) : (a.x < b.x); } 
    
    int N, c[MAX_W]; 
    inline int lb(int x) { return x & -x; } 
    void add(int x, int v) { while (x <= N) c[x] += v, x += lb(x); } 
    int sum(int x) { int res = 0; while (x > 0) res += c[x], x -= lb(x); return res; } 
    void Div(int l, int r) { 
        if (l == r) return ; 
        int mid = (l + r) >> 1; 
        Div(l, mid); Div(mid + 1, r); 
        int j = l; 
        for (int i = mid + 1; i <= r; i++) { 
            if (t[i].id == 0) continue; 
            for (; t[j].x <= t[i].x && j <= mid; ++j) if (t[j].id == 0) add(t[j].y, t[j].w); 
            ans[t[i].id] += sum(t[i].y) * t[i].w; 
        } 
        for (int i = l; i < j; i++) if (t[i].id == 0) add(t[i].y, -t[i].w); 
        inplace_merge(&t[l], &t[mid + 1], &t[r + 1], cmp_x); 
    } 
    int main () { 
        gi(); N = gi(); int tot = 0, cnt = 0; 
        for (;;) { 
            int op = gi(); if (op == 3) break; 
            int x = gi(), y = gi(); 
    		if (op == 1) t[++tot] = (Node){x, y, 0, gi()}; 
    		else { 
    		    int _x = gi(), _y = gi(); ++cnt; 
    		    t[++tot] = (Node){_x, _y, cnt, 1}; 
    		    t[++tot] = (Node){_x, y - 1, cnt, -1}; 
    		    t[++tot] = (Node){x - 1, _y, cnt, -1}; 
    		    t[++tot] = (Node){x - 1, y - 1, cnt, 1}; 
    	    } 
        } 
        Div(1, tot); 
        for (int i = 1; i <= cnt; i++) printf("%d
    ", ans[i]); 
        return 0; 
    } 
    
  • 相关阅读:
    Asp.Net : 实现一个 DataSet 或DataTable SELECT DISTINCT (字段唯一性)
    Jquery 局部刷新及 表单取值赋值 处理返回json数据 一些基本操作
    C# 自动化模型编辑Word
    泛型集合List的添加、访问、遍历和删除
    泛型转DataTable方法
    服务器按钮如何通过js验证再触发提交事件?
    Asp.Net 无限分类生成表格 &lt;后台自定义输出table&gt;
    table的innerHTML “未知运行错误”。
    js 截取字符串的方法 C# 正则判断数字及截取字符
    Microsoft Office Visio 2007 设计数据库关系图
  • 原文地址:https://www.cnblogs.com/heyujun/p/10121948.html
Copyright © 2011-2022 走看看