• cogs1752[boi2007]mokia 摩基亚 (cdq分治)


    【题目描述】

    摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统。和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米。但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题。

    在定位系统中,世界被认为是一个W×W的正方形区域,由1×1的方格组成。每个方格都有一个坐标(x,y)1<=x,y<=W。坐标的编号从1开始。对于一个4×4的正方形,就有1<=x<=4,1<=y<=4(如图):

    请帮助Mokia公司编写一个程序来计算在某个矩形区域内有多少名用户。

    【输入格式】

    有三种命令,意义如下:

    命令 参数 意义
    0 W 初始化一个全零矩阵。本命令仅开始时出现一次。
    1 x y A 向方格(x,y)中添加A个用户。A是正整数。
    2 X1 Y1 X2 Y2 查询X1<=x<=X2Y1<=y<=Y2所规定的矩形中的用户数量
    3 无参数 结束程序。本命令仅结束时出现一次。

    【输出格式】

    对所有命令2,输出一个一行整数,即当前询问矩形内的用户数量。

    【输入样例】

    0 4

    1 2 3 3

    2 1 1 3 3

    1 2 2 2

    2 2 2 3 4

    3

    【输出样例】

    3

    5

    【提示】

    输入 输出 意义
    0 4   大小为4×4的全零正方形
    1 2 3 3   (2,3)方格加入3名用户
    2 1 1 3 3   查询矩形1<=x<=3,1<=y<=3内的用户数量
      3 查询结果
    1 2 2 2   (2,2)方格加入2名用户
    2 2 2 3 4   查询矩形2<=x<=3,2<=y<=4内的用户数量
      5 查询结果
    3   终止程序

    【数据规模】

    1<=W<=2000000

    1<=X1<=X2<=W

    1<=Y1<=Y2<=W

    1<=x,y<=W

    0<A<=10000

    命令1不超过160000个。

    命令2不超过10000个。

    【来源】

    Balkan Olypiad in Informatics 2007,Mokia

     

    Solution

    cdq分支模板题

    #include <stdio.h>
    #include <algorithm>
    int w, C[2000010], ans[10010];
    struct Que{
    	int x, y, v, tp, _id;
    }q[200010];
    bool cmp(Que a, Que b) {return a.x < b.x;}
    inline void add(int i, int d){
    	for(; i <= w; i += i & (-i))
    		C[i] += d;
    }
    inline int sum(int i){
    	int res = 0;
    	for(; i; i -= i & (-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);
    	std::sort(q + l, q + mid + 1, cmp);
    	std::sort(q + mid + 1, q + r + 1, cmp);
    	int j = l;
    	for(int i = mid + 1; i <= r; i++){
    		for(; j <= mid && q[j].x <= q[i].x; j++)
    			if(q[j].tp == 1) add(q[j].y, q[j].v);
    		if(q[i].tp == 2) ans[q[i]._id] += q[i].v * sum(q[i].y);
    	}
    	for(int i = l; i < j; i++)
    		if(q[i].tp == 1) add(q[i].y, -q[i].v);
    }
    int main(){
    	int op, a, b, c, d, id = 0, tot = 0;
    	freopen("mokia.in", "r", stdin), freopen("mokia.out", "w", stdout);
    	while(scanf("%d", &op) && op != 3){
    		if(op == 0)
    			scanf("%d", &w);
    		else if(op == 1){
    			scanf("%d%d%d", &a, &b, &c);
    			q[++id] = (Que) {a, b, c, 1, 0};
    		}
    		else{
    			++tot;
    			scanf("%d%d%d%d", &a, &b, &c, &d);
    			q[++id] = (Que) {a - 1, b - 1, 1, 2, tot};
    			q[++id] = (Que) {c, d, 1, 2, tot};
    			q[++id] = (Que) {a - 1, d, -1, 2, tot};
    			q[++id] = (Que) {c, b - 1, -1, 2, tot};
    		}
    	}
    	cdq(1, id);
    	for(int i = 1; i <= tot; i++)
    		printf("%d
    ", ans[i]);
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    

      

  • 相关阅读:
    C# 关于X86/X64/AnyCpu 的关系
    MongoDB
    AJAX向服务器发送与请求(四)
    jsplumb事件 easyflow
    Vue接收Asp.Net Core传递的文件并下载,接收application/octetstream类型文件流并下载
    docker安装elasticsearch7.16.3集群
    阿里云镜像站
    虚拟机安装Ubuntu20.04.2 Server TLS
    docker安装elasticsearch7.16.3集群 配置身份认证
    Sqlserver查询阻塞的SQL语句
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6413151.html
Copyright © 2020-2023  润新知