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

    题目描述

    你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

    命令

    参数限制

    内容

    1 x y A

    1<=x,y<=N,A是正整数

    将格子x,y里的数字加上A

    2 x1 y1 x2 y2

    1<=x1<= x2<=N

    1<=y1<= y2<=N

    输出x1 y1 x2 y2这个矩形内的数字和

    3

    终止程序


    输入格式

    输入文件第一行一个正整数N。
    接下来每行一个操作。
     

    输出格式

    对于每个2操作,输出一个对应的答案。
     

    样例输入

    4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3
     
    

    样例输出

    3
    5
     
    

    提示

    1<=N<=500000,操作数不超过200000个,内存限制20M。
    对于100%的数据,操作1中的A不超过2000。
     
    思路分析 :
      CDQ分治真有意思!
      这个题目我们只需要将所给的条件变换一下,不就变成了一道裸的题目啦,题目所给的是在一个二维的空间中,我们可以加一维时间在上边,变成一个三维偏序。
    代码示例 : (未测试)
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 6e5+5;
    
    int n;
    int k = 1;
    struct node
    {
    	int x, y, z, num, sum;
    	node(int _x=0, int _y=0, int _z=0, int _num=0, int _sum=0):x(_x),y(_y),z(_z),num(_num),sum(_sum){}
    
    	bool operator< (const node &v)const{
    		if (x != v.x) return x < v.x;
    		if (y != v.y) return y < v.y;
    		return z < v.z; 
    	}
    }arr[maxn], f[maxn];
    int c[maxn];
    int lowbit(int x){return x&(-x);}
    void add(int p, int num){
    	for(int i = p; i <= n; i += lowbit(i)) c[i] += num; 
    }
    int query(int x){
    	int res = 0;
    	for(int i = x; i ; i -= lowbit(i)){
    		res += c[i];
    	}
    	return res;
    }
    void CDQ(int l, int r){
    	if (l == r) return;
    	int mid = (l+r)>>1;
    	CDQ(l, mid);
    	CDQ(mid+1, r);
    	int	p1 = l, p2 = mid+1;
    	int num = 0;
    	for(int i = l; i <= r; i++){
    		if (p1<=mid && (p2 > r || arr[p1].y <= arr[p2].y)){
    			add(arr[p1].z, arr[p1].num);
    			f[num++] = arr[p1++];
    		}
    		else {
    			int num2 = query(arr[p2].z);
    			arr[p2].sum += num2;
    			f[num++] = arr[p2++];
    		}
    	}
    	num = 0;
    	for(int i = l; i <= r; i++){
    		if (i <= mid) add(arr[i].z, -arr[i].num);
    		arr[i] = f[num++];
    	}
    }
    
    vector<int>ve;
    int main () {
    	int pt;
    	int x1, y1, x2, y2, num;
    	int time = 1;
    	cin >> n;
    	
    	while(1){
    		scanf("%d", &pt);
    		if (pt == 3) break;
    		else if (pt == 1) {
    			scanf("%d%d%d", &x1, &y1, &num);
    			x1++, y1++;
    			arr[k++] = node(time++, x1, y1, num, num);			
    		}
    		else {
    			scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    			x1++, y1++, x2++, y2++;
    			ve.push_back(k);
    			arr[k++] = node(time, x1-1, y1-1, 0, 0);
    			arr[k++] = node(time, x1-1, y2, 0, 0);
    			arr[k++] = node(time, x2, y1-1, 0, 0);
    			arr[k++] = node(time++, x2, y2, 0, 0);
    		}
    	}
    	CDQ(1, k-1);sort(arr+1, arr+k);
    
    	
    	for(int i = 0; i < ve.size(); i++){
    		int x = ve[i];
    		int ans = arr[x+3].sum+arr[x].sum-arr[x+1].sum-arr[x+2].sum;
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    /*
    10
    2 1 1 3 3
    1 1 1 1
    1 2 1 2
    1 3 3 1
    1 4 4 4
    2 1 1 3 3
    2 1 1 4 4
    3
    */
    
     
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    过滤器实例——字符编码Filter
    pcap文件格式分析
    jsp常见获取地址函数之间的不同
    将抓到的pcap文件中Http包转换为可读的txt格式
    DBA入门之Oracle数据库参数文件
    查询session status各项统计数据的前三名
    查询正在做的排序操作
    DBUtils的handler
    DBA入门之认识检查点(Checkpoint)
    show_space_by_tom
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9531672.html
Copyright © 2011-2022 走看看