zoukankan      html  css  js  c++  java
  • 【cdq分治】【P4390】[BOI2007]Mokia 摩基亚

    Description

    给你一个 (W~ imes~W) 的矩阵,每个点有权值,每次进行单点修改或者求某子矩阵内权值和,允许离线

    Input

    第一行是两个数字 (0) 和矩阵大小 (W)

    下面每行可能会出现如下参数

    (1,x,y,A) 单点修改格子 (x,y)(A)

    (2,x_1,y_1,x_2,y_2) 查询给定矩阵的权值和

    (3) 结束查询与修改

    Output

    对每个查询给出一行作为答案

    Hint

    (1~leq~W~leq~2000000)

    修改不超过 (1.6e5)

    查询不超过 (1e4)

    保证答案在整形范围内

    Solution

    这不傻逼题,直接树状数组套treap完事了

    我们考虑离线乱搞一下

    将查询改为每次查询二维前缀和容斥的形式进行四次单点查询。

    我们考虑对 (x,y) 的前缀和查询:

    我们只需要考虑修改时间在该次查询之前,且 (x_0~leq~x~land~y_0~leq~y) 的修改操作 ((x_0,y_0))

    我们发现这是一个标准的cdq分治模型:

    第一维为时间序,第二维为 (x) 坐标,第三维为 (y) 坐标。

    时间序默认有序,每次考虑前半部分的 (x_0~leq~x) 的点中 (y_0~leq~y) 的点对答案的贡献,用树状数组来统计这部分答案

    时间复杂度 (O(n~log^2 n)),空间复杂度 (O(n~log n))

    Code

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #ifdef ONLINE_JUDGE
    #define freopen(a, b, c)
    #endif
    
    typedef long long int ll;
    
    namespace IPT {
    	const int L = 1000000;
    	char buf[L], *front=buf, *end=buf;
    	char GetChar() {
    		if (front == end) {
    			end = buf + fread(front = buf, 1, L, stdin);
    			if (front == end) return -1;
    		}
    		return *(front++);
    	}
    }
    
    template <typename T>
    inline void qr(T &x) {
    	char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
    	if (lst == '-') x = -x;
    }
    
    namespace OPT {
    	char buf[120];
    }
    
    template <typename T>
    inline void qw(T x, const char aft, const bool pt) {
    	if (x < 0) {x = -x, putchar('-');}
    	int top=0;
    	do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
    	while (top) putchar(OPT::buf[top--]);
    	if (pt) putchar(aft);
    }
    
    const int maxn = 2000010;
    
    struct OP {
    	int x, y, id, v;
    
    	inline void print() {
    		std::cerr << x << ' ' << y << ' ' << id << ' ' << v << std::endl;
    	}
    };
    std::vector<OP> Q;
    
    int n, cnt;
    int ans[maxn], tree[maxn];
    
    int query(int);
    int lowbit(int);
    void cdq(int, int);
    void update(int, int);
    
    int main() {
    	freopen("1.in", "r", stdin);
    	int a, b, c, d;
    	qr(a); qr(n); a = 0; qr(a); 
    	while (a != 3) {
    		if (a == 1) {
    			a = b = c = 0; qr(a); qr(b); qr(c);
    			Q.push_back({a, b, 0, c});
    		} else {
    			a = b = c = d = 0; qr(a); qr(b); qr(c); qr(d);
    			Q.push_back({c, d, ++cnt, 1});
    			Q.push_back({a - 1, b - 1, cnt, 1});
    			Q.push_back({c, b - 1, cnt, -1});
    			Q.push_back({a - 1, d, cnt, -1});
    		}
    		a = 0; qr(a);
    	}
    	cdq(0, Q.size() - 1);
    	for (int i = 1; i <= cnt; ++i) qw(ans[i], '
    ', true);
    	return 0;
    }
    
    void cdq(int l, int r) {
    	if (l == r) return;
    	int mid = (l + r) >> 1;
    	cdq(l, mid); cdq(mid + 1, r);
    	std::vector<OP>temp;
    	int pre = l;
    	for (int i = mid + 1; i <= r; ++i) {
    		while ((pre <= mid) && (Q[pre].x <= Q[i].x)) {
    			if (Q[pre].id == 0) update(Q[pre].y, Q[pre].v);
    			temp.push_back(Q[pre++]);
    		}
    		ans[Q[i].id] += Q[i].v * query(Q[i].y);
    		temp.push_back(Q[i]);
    	}
    	for (int i = l; i < pre; ++i) if (Q[i].id == 0) update(Q[i].y, -Q[i].v);
    	while (pre <= mid) temp.push_back(Q[pre++]);
    	for (int i = l; i <= r; ++i) Q[i] = temp[i - l];
    }
    
    inline int lowbit(int x) {return x & -x;}
    
    void update(int x, int v) {
    	while (x <= n) {
    		tree[x] += v; x += lowbit(x);
    	}
    }
    
    int query(int x) {
    	int _ret = 0;
    	while (x) {
    		_ret += tree[x];
    		x -= lowbit(x);
    	}
    	return _ret;
    }
    
  • 相关阅读:
    可爱的中国电信 请问我们的电脑还属于我们自己吗?
    了解客户的需求,写出的代码或许才是最优秀的............
    DELPHI DATASNAP 入门操作(3)简单的主从表的简单更新【含简单事务处理】
    用数组公式获取字符在字符串中最后出现的位置
    在ehlib的DBGridEh控件中使用过滤功能(可以不用 MemTableEh 控件 适用ehlib 5.2 ehlib 5.3)
    格式化json返回的时间
    ExtJs中使用Ajax赋值给全局变量异常解决方案
    java compiler level does not match the version of the installed java project facet (转)
    收集的资料(六)ASP.NET编程中的十大技巧
    收集的资料共享出来(五)Asp.Net 权限解决办法
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10423148.html
Copyright © 2011-2022 走看看