题解报告——Mokia

题目描述

摩尔瓦多的移动电话公司摩基亚(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<=X2,Y1<=y<=Y2所规定的矩形中的用户数量
  • 3 无参数 结束程序。本命令仅结束时出现一次。

输出格式:

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

输入输出样例

输入样例#1:

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

输出样例#1:

3
5

说明

对于所有数据:

1<=W<=2000000
1<=X1<=X2<=W
1<=Y1<=Y2<=W
1<=x,y<=W
0<A<=10000
命令1不超过160000个。
命令2不超过10000个。



【思路分析】

CDQ模板题,由于网上博客看不懂,所以只有自行脑补,可能写得有点丑,有点慢。。。自行体会。。。

【代码实现】

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define lowbit(x) x&(-x)
 4 using namespace std;
 5 const int N=2e6+5;
 6 struct sd{
 7     int kind,x,y,val,id;
 8 }que[N];
 9 int ans[N],t[N<<2],n,w,ord,cnt,cot;
10 bool cmp(sd a,sd b)
11 {
12     if(a.x!=b.x) return a.x<b.x;
13     if(a.y!=b.y) return a.y<b.y;
14     return a.kind<b.kind;
15 }
16 void add(int v,int ww)
17 {
18     for(;v<=w;v+=lowbit(v))
19     t[v]+=ww;
20 }
21 int ask(int v)
22 {
23     int res=0;
24     for(;v;v-=lowbit(v))
25     res+=t[v];
26     return res;
27 }
28 void CDQ(int l,int r)
29 {
30     if(l==r) return;
31     int mid=(l+r)>>1;
32     CDQ(l,mid),CDQ(mid+1,r);
33     sort(que+l,que+mid+1,cmp),sort(que+mid+1,que+r+1,cmp);
34     int i=l,j=mid+1;
35     for(;j<=r;j++)
36     {
37         while(que[i].x<=que[j].x&&i<=mid)
38         {
39             if(!que[i].kind) add(que[i].y,que[i].val);
40             i++;
41         }
42         if(que[j].kind) ans[que[j].id]+=que[j].val*ask(que[j].y);
43     }
44     for(j=l;j<i;j++) if(!que[j].kind) add(que[j].y,-que[j].val);
45 }
46 int main()
47 {
48     scanf("%d%d",&n,&w);
49     while(1)
50     {
51         int a,b,c,d;
52         scanf("%d",&ord);if(ord==3) break;
53         scanf("%d%d%d",&a,&b,&c);
54         if(ord==1) {que[++cnt]=(sd){0,a,b,c,0};}
55         if(ord==2)
56         {
57             scanf("%d",&d);
58             que[++cnt]=(sd){1,a-1,b-1,1,++cot};
59             que[++cnt]=(sd){1,c,d,1,cot};
60             que[++cnt]=(sd){1,a-1,d,-1,cot};
61             que[++cnt]=(sd){1,c,b-1,-1,cot};
62         }
63     }
64     CDQ(1,cnt);
65     for(int i=1;i<=cot;i++) printf("%d\n",ans[i]);
66     return 0;
67 }

原文地址:https://www.cnblogs.com/genius777/p/9124398.html

时间: 2024-08-30 05:33:12

题解报告——Mokia的相关文章

cojs 强连通图计数1-2 题解报告

OwO 题目含义都是一样的,只是数据范围扩大了 对于n<=7的问题,我们直接暴力搜索就可以了 对于n<=1000的问题,我们不难联想到<主旋律>这一道题 没错,只需要把方程改一改就可以了 首先我们考虑不合法的方案强连通分量缩点后一定是DAG 考虑子问题:DAG计数 做法可以参考<cojs DAG计数1-4 题解报告> 这里给出转移方程 f(n)=sigma((-1)^(k-1)*C(n,k)*2^(k*(n-k))*f(n-k)) 如果考虑上强连通分量缩点的情况呢? 我

2016 年宁波工程学院第七届ACM校赛题解报告

2016 年宁波工程学院第七届ACM校赛题解报告 本题解代码直接为比赛代码,仅供参考. A,B,C,D,G,H,J,K,L,M 来自 Ticsmtc 同学. F 来自 Gealo 同学. E,I 来自Alex 学长. Promblem A :    Two Sum 时间限制: 1 Sec  内存限制: 64 MB 题目描述: 给出n个数,另外给出?个整数S,判断是否可以从中取出2个数,使得这两个数的和是S. 输入: 第?行有个整数T(1 <= T <= 10),代表数据组数. 对于每组数据,第

线段树&#183;题解报告

线段树·题解报告 参考资料 ·课件 线段树 --刘汝佳 统计的力量,线段树全接触 --张昆玮 ·Blog [完全版]线段树 从普通线段树到zkw线段树 [总结][数据结构]ZKW线段树详解 选题目录 · Hdu1166 敌兵布阵(单点更新,区间求和) · Hdu1754 I Hate It(单点更新,RMQ) · Hdu3308 LCIS(单点更新,区间并) · Poj3468 A Simple Problem with Integers(区间加减,区间求和) · Poj2777 Count C

题解报告:hdu 1162 Eddy&#39;s picture

Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to become a painter.Every day Eddy draws pictures in his small room, and he usually puts out his newest pictures to let his friends appreciate. but the result i

题解报告:poj 3320 Jessica&#39;s Reading Problem(尺取法)

Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The au

题解报告:poj 2480 Longge&#39;s problem(欧拉函数)

Description Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N. 

题解报告(CDUT暑期集训——第三场)

题解报告(CDUT暑期集训--第三场) A - Problem A. Ascending Rating HDU - 6319 思路:单调队列板子题?(但是弱的一批的我还是不会用(有空补上 用的滑动窗口算法 按着题解的从后往前做(ps:菜是原罪 AC代码 #include<stdio.h> #include<iostream> #include<math.h> #include<algorithm> #include<string.h> #incl

CFEducational Codeforces Round 66题解报告

CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第\(k\)小的值 那么问题就变成了 每一个数变成了\([x-mid,x+mid]\)的一段区间,如果有一个位置被覆盖了超过\(k\)次 那么\(mid\)一定合法 类似括号匹配 每次碰到左端点就贡献+1 右端点就统计答案然后-1 维护答案的同时顺便维护位置就好了 #include<cstdio>

CF1169(div2)题解报告

CF1169(div2)题解报告 A 不管 B 首先可以证明,如果存在解 其中必定有一个数的出现次数大于等于\(\frac{m}{2}\) 暴力枚举所有出现次数大于等于$\frac{m}{2} $的数 剩下的数看看有没有一个公共数即可 由于出现次数大于等于$\frac{m}{2} $的数不会太多 所以时间复杂度应该是\(O(n)\)的 #include<cstdio> #include<iostream> #include<queue> #include<algo