1266 - Points in Rectangle[二维树状数组 + 容斥原理]

1266 - Points in Rectangle
Time Limit: 2 second(s)Memory Limit: 32 MB

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

Output for 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

Case 1:

2

0

2

3

Note

Dataset is huge, use faster I/O methods.


PROBLEM SETTER: JANE ALAM JAN

题目大意:给你两种操作,0 x y代表给坐标(x,y)上添加一个点
1 x1 y1 x2 y2 代表查询对角线为(x1,y1)----(x2,y2)矩形内的点
一开始没有想到容斥原理,所以逗比了
这题要用容斥原理

代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAX_N = 1111;
int T,q,bit[MAX_N][MAX_N],n,cmd,x1,yy1,x2,y2;
bool vis[MAX_N][MAX_N];

void add(int x,int y,int num){
    for(int i=x;i<=n;i+=i&-i){
        for(int j=y;j<=n;j+=j&-j){
            bit[i][j] += num;
        }
    }
}

int sum(int x,int y){
    int res = 0;
    for(int i=x;i>0;i-=i&-i){
        for(int j=y;j>0;j-=j&-j){
            res += bit[i][j];
        }
    }
    return res;
}

int main(){
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        memset(bit,0,sizeof(bit));
        memset(vis,0,sizeof(vis));
        n = 1111;
        printf("Case %d:\n",t);
        scanf("%d",&q);
        while( q-- ){
            scanf("%d",&cmd);
            if(cmd==0){
                scanf("%d%d",&x1,&yy1);
                x1+=2; yy1+=2;
                if(!vis[x1][yy1]) {
                    add(x1,yy1,1);
                    vis[x1][yy1] = true;
                }
            } else {
                scanf("%d%d%d%d",&x1,&yy1,&x2,&y2);
                x1+=2; yy1+=2; x2+=2; y2+=2;
                int ans = sum(x2,y2);
                int ans2 = sum(x1-1,y2);
                int ans3 = sum(x2,yy1-1);
                int ans4 = sum(x1-1,yy1-1);
                printf("%d\n",ans-ans2-ans3+ans4);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值