摩基亚Mokia

P1948 - 【BOI2007】摩基亚Mokia

Description

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

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

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

Input

有三种命令,意义如下:

命令     参数                     意义

0         W                         初始化一个全零矩阵。本命令仅开始时出现一次。

1         x y A                     向方格(x,y)中添加A个用户。A是正整数。

2         X1 Y1 X2 Y2         查询X1<=x<=X2,Y1<=y<=Y2所规定的矩形中的用户数量

3         无参数                结束程序。本命令仅结束时出现一次。

Output

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

Sample Input

0 4

1 2 3 3

2 1 1 3 3

1 2 2 2

2 2 2 3 4

3

Sample Output

3

5

Hint

样例提示:

输入             输出         意义

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个。

Source

Balkan Olypiad in Informatics 2007,Mokia

陈丹琦分治, 分治, 树状数组

Accepted entrance

CDQ分治,把一个矩阵的询问拆成四个,运用容斥原理,给每个询问一个时间顺序。可以发现,修改只是单个格子修改,只有修改的这个各自的横坐标小于询问的横坐标,才会对这个询问产生贡献,刚好是三维的(x,y,time),于是time排序,xCDQ分治,y树状数组维护,还是一个样的,计算左区间[l,mid]对右区间[mid+1,r]的贡献,统计答案。

参考博客:http://wulala.logdown.com/posts/207262-boi-2007-mokia

 1 #define ll long long
 2 #define rep(i,a,b) for(int i=a;i<=b;i++)
 3 #define lowbit(p) p & (-p)
 4 #include<algorithm>
 5 #include<iostream>
 6 #include<iomanip>
 7 #include<cstring>
 8 #include<cstdlib>
 9 #include<cstdio>
10 #include<queue>
11 #include<ctime>
12 #include<cmath>
13 #include<stack>
14 #include<map>
15 #include<set>
16 using namespace std;
17 const int N=160010*4+10000;
18 int tot,W,C[2000000+10],q;
19 struct Q{
20     int x,y,k,q,v,od;//  k 种类  q Index_ans   v val or -+   id _ time
21 }que[N],np[N];
22 int Ans[N];
23 bool comp(const Q &a,const Q &b) {
24     return a.x<b.x;
25 }
26 void add(int p,int x) {
27     if(!p) return;
28     while(p<=W) C[p]+=x,p+=lowbit(p);
29 }
30 int getsum(int p) {
31     int sum=0;
32     while(p) sum+=C[p],p-=lowbit(p);
33     return sum;
34 }
35 int gi() {
36     int res=0,f=1;
37     char ch=getchar();
38     while((ch<‘0‘||ch>‘9‘)&&ch!=‘-‘) ch=getchar();
39     if(ch==‘-‘) ch=getchar(),f=-1;
40     while(ch>=‘0‘&&ch<=‘9‘) res=res*10+ch-‘0‘,ch=getchar();
41     return res*f;
42 }
43 void CDQ(int l,int r)  {
44     if(l==r) return;
45     int mid=(l+r)>>1;
46     int l1=l,l2=mid+1;
47     rep(i,l,r) if(que[i].od<=mid) np[l1++]=que[i];else np[l2++]=que[i];
48     rep(i,l,r) que[i]=np[i];
49     l1=l;
50     rep(i,mid+1,r) if(que[i].k==2){
51     for(;l1<=mid&&que[l1].x<=que[i].x;l1++) {
52         if(que[l1].k==1)
53         add(que[l1].y,que[l1].v);
54     }
55     Ans[que[i].q]+=getsum(que[i].y)*que[i].v;
56     }
57     rep(i,l,l1-1) if(que[i].k==1) add(que[i].y,-que[i].v);
58     CDQ(l,mid) , CDQ(mid+1,r);
59 }
60 void work() {
61     while(1) {
62     int Type=gi(),x,y;
63     if(Type==3) break;
64     if(Type==1) {
65         x=gi(),y=gi();int c=gi();
66         que[++tot]=(Q){x,y,1,0,c,tot};
67     }
68     else {
69         ++q;
70         x=gi(),y=gi();int u2=gi(),v2=gi();
71         que[++tot]=(Q){x-1,y-1,2,q,1,tot};
72         que[++tot]=(Q){x-1,v2,2,q,-1,tot};
73         que[++tot]=(Q){u2,y-1,2,q,-1,tot};// y-1 v2-1
74         que[++tot]=(Q){u2,v2,2,q,1,tot};
75     }
76     }
77
78     sort(que+1,que+tot+1,comp);
79     CDQ(1,tot);
80     return;
81 }
82 int main() {
83         freopen("mokia.in","r",stdin);
84         freopen("mokia.out","w",stdout);
85
86     int Type=gi();
87     W=gi();
88     work();
89     rep(i,1,q) printf("%d\n",Ans[i]);
90     return 0;
91 }

时间: 2024-10-08 07:38:08

摩基亚Mokia的相关文章

【BOI2007】摩基亚Mokia

P1948 - [BOI2007]摩基亚Mokia Description 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W * W的正方形区域,由1 * 1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始

COJS 1752. [BOI2007]摩基亚Mokia

1752. [BOI2007]摩基亚Mokia ★★★   输入文件:mokia.in   输出文件:mokia.out   简单对比时间限制:5 s   内存限制:128 MB [题目描述] 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如“给定区域内有多少名用户?”的问题. 在定位系统中,世界被认为是一个W*W的正方形区域,由1*1的方格组成.每

【COGS1752】 BOI2007—摩基亚Mokia

http://cogs.pro/cogs/problem/problem.php?pid=1752 (题目链接) 题意 给出$n*n$的棋盘,单点修改,矩阵查询. Solution 离线以后CDQ分治.每一层按照$Y$排序,然后询问用前缀和拆成$4$个,树状数组维护一下就可以了. 细节 ? 代码 // cogs1752 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring

COGS1752. [BOI2007]摩基亚Mokia CDQ

CDQ的板子题 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 2000010 using namespace std; inline int read() { int sum=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'

Bzoj1176:Mokia&amp;Cogs1752:[BOI2007]摩基亚Mokia

题目 Cogs 没有Bzoj的权限号 Sol 离线,\(CDQ\)分治,把询问拆成\(4\)个,变成每次求二位前缀和 那么只要一个修改操作(关键字为时间,\(x\),\(y\))都在这个询问前,就可以累计答案 那么就成了偏序问题了,直接\(CDQ\) 注意当\(x\)相等时要把修改丢在前面 # include <bits/stdc++.h> # define IL inline # define RG register # define Fill(a, b) memset(a, b, size

[BOI2007]Mokia 摩基亚

upd:\((x1,y1)(x2,y2)\)表示以\((x1,y1)\)为左上端点 \((x2,y2)\)为右下端点的矩形 本来以为是一道二位树状数组的模板,但是看数据范围之后就放弃了,边界既然到了2000000,那么我们只能使用其他办法来代替树状数组 于是,CDQ分治就诞生了! 此题我们可以把问题转化成cdq分治模板 回忆一下二位树状数组是怎么求二维区间查询的:对于区间[x1,y1][x2,y2],我们把它转化成$ (1,1)(x1-1,y1-1)+(1,1)(x2,y2)-(1,1)(x1-

[BOI2007] Mokia

题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W×W的正方形区域,由1×1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始.对于一个4×4的正方形,就有1<=x<=4,1<=y&

题解报告——Mokia

题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W×W的正方形区域,由1×1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始.对于一个4×4的正方形,就有1<=x<=4,1<=y&

CDQ分治总结

目录 例题 园丁的烦恼 树状数组1 陌上花开(三维偏序) 摩基亚 同步:https://buringstraw.win/index.php/archives/50/ 经过了一周的划水,我终于搞懂了cdq分治. 总的来说,cdq分治处理偏序问题就是 先把左边和右边当成一个完整的问题处理 然后把左边对右边的影响合并到右边 例题 园丁的烦恼 传送门 求静态区域内的点数,二维偏序模板题. #include<cstdio> #include<algorithm> const int MAXN