Points in Rectangle (树状数组)
来源:互联网 发布:ubuntu中文输入法 编辑:程序博客网 时间:2024/06/05 20:40
Description
As the name says, this problem is about finding the number of points in a rectangle whose sides are parallel to axis. All the points and rectangles consist of 2D Cartesian co-ordinates. A point that lies in the boundary of a rectangle is considered inside.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing an integer q (1 ≤ q ≤ 30000) denoting the number of queries. Each query is either one of the following:
1) 0 x y, meaning that you have got a new point whose co-ordinate is (x, y). But the restriction is that, if a point (x, y) is already listed, then this query has no effect.
2) 1 x1 y1 x2 y2 meaning that you are given a rectangle whose lower left co-ordinate is (x1, y1) and upper-right corner is (x2, y2); your task is to find the number of points, given so far, that lie inside this rectangle. You can assume that (x1 < x2, y1 < y2).
You can assume that the values of the co-ordinates lie between 0 and 1000 (inclusive).
Output
For each case, print the case number in a line first. Then for each query type (2), you have to answer the number of points that lie inside that rectangle. Print each of the results in separated lines.
Sample Input
1
9
0 1 1
0 2 6
1 1 1 6 6
1 2 2 5 5
0 5 5
1 0 0 6 5
0 3 3
0 2 6
1 2 1 10 10
Sample Output
Case 1:
2
0
2
3
1.在平面上选一点
2.选择一个与x,y轴平行的矩形,问矩形中含多少点。
典型的二维树状数组
#include<iostream>#include<cstring>#include<cstdio>using namespace std;int tree[1005][1005],N;bool mark[1005][1005];void update(int x,int y,int change){ while(x<=1004) { int y1=y; while(y1<=1004) { tree[x][y1]+=change; y1+=y1&(y1^(y1-1)); } x+=x&(x^(x-1)); }}int query(int x,int y){ int coun=0; while(x>0) { int y2=y; while(y2>0) { coun+=tree[x][y2]; y2-=y2&(y2^(y2-1)); } x-=x&(x^(x-1)); } return coun;}int main(){ int times; scanf("%d",×); for(int time=1;time<=times;++time) { memset(tree,0,sizeof(tree)); memset(mark,0,sizeof(mark)); int q; printf("Case %d:\n",time); scanf("%d",&q); for(int i=1;i<=q;++i) { int que; scanf("%d",&que); if(que) { int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); // int c22=query(x2,y2); printf("%d\n",query(x2+1,y2+1)-query(x2+1,y1)-query(x1,y2+1)+query(x1,y1)); } else { int x,y; scanf("%d%d",&x,&y); if(mark[x+1][y+1]) continue; else { mark[x+1][y+1]=true; update(x+1,y+1,1); } } } } return 0;}
其中有两点需要注意
1.树状数组的下标应当大于0,若题中含0,或负数,可以加上最小负数的绝对值+1,全部转为正数。
2.常常涉及到容斥定理,对于其中的边界取舍,应当注意最好画个草图,以区分界限,保证只统计一次。
- Points in Rectangle (树状数组)
- [树状数组]LightOJ 1266 - Points in Rectangle
- 1266 - Points in Rectangle[二维树状数组 + 容斥原理]
- Lightoj1267 Points in Rectangle (II)(排序+树状数组)
- LightOJ 1112 Curious Robin Hood && LightOJ 1266 Points in Rectangle(树状数组)
- Light OJ 1266 - Points in Rectangle
- POJ 2464 Brownie Points II(树状数组||线段树)
- POJ 2464 Brownie Points II(树状数组+扫描线)
- UVA 10869 - Brownie Points II(树状数组+离散化)
- POJ 2464 Brownie Points II(树状数组)
- poj2464 Brownie Points II 树状数组
- UVA 10869 - Brownie Points II(树状数组)
- uva 10869 - Brownie Points II(树状数组)
- Codeforces 19D Points(树状数组)
- POJ 2464 Brownie Points II --树状数组
- poj 2464 Brownie Points II 树状数组
- [ifrog 1069 Rectangle Cover] 二维树状数组
- Poj 3416 Crossing + Poj 2464 Brownie Points II (树状数组)
- NVIDIA JETSON 连接九轴IMU传感器(GY-85模块)
- 驱动编程-idt hook--中断描述符表
- 分布式配置管理平台 Disconf
- Spring @PostConstruct and @PreDestroy example
- getdate.php var_dump($arry);
- Points in Rectangle (树状数组)
- 《java入门第一季》之面向对象面试题(面向对象都做了哪些事情)
- android 利用左右滑动手势实现avtivity的跳转
- [CDQ分治] codeforces 669E. Little Artem and Time Machine
- Spark组件之GraphX学习14--TriangleCount实例和分析
- burnside引理
- 使用mktime 函数取得一个日期的时间戳
- 第六周项目二-带武器的游戏角色
- Linux下文件编码转换