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;
    }
    
  • 相关阅读:
    EntityFramework 启用迁移 EnableMigrations 报异常 "No context type was found in the assembly"
    JAVA 访问FTP服务器示例(2)
    NuGet Package Manager 更新错误解决办法
    JAVA 访问FTP服务器示例(1)
    RemoteAttribute 的使用问题
    诡异的 javascript 变量
    javascript apply用法
    Babun 中文乱码
    GSM呼叫过程
    转站博客园
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10423148.html
Copyright © 2011-2022 走看看