[树状数组]LightOJ 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 integerT (≤ 10), denoting the number of test cases.

Each case starts with a line containing an integerq (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 x1y1x2y2meaning 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 between0and1000(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.

题意:在(0,0)-(1000,1000)的矩阵中给定若干个询问,询问分为两种,第一种把某个点置1,第二种,统计一个矩形里面1的个数(包含边界),很明显使用二维树状数组实现(单点更新,范围求和)。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1111,BOUND = 1001;
int c[MAXN][MAXN],t,q,type,x1,x2,y1,y2;
void build(){
    memset(c,0,sizeof(c));
}
int lowbit(int x){
    return x&(-x);
}
int sum(int px,int py){
    int s = 0;
    for(int i=px;i>0;i-=lowbit(i)){
        for(int j=py;j>0;j-=lowbit(j)){
            s+=c[i][j];
        }
    }
    return s;
}
void add(int px,int py){
    for(int i=px;i<=BOUND;i+=lowbit(i)){
        for(int j=py;j<=BOUND;j+=lowbit(j)){
            c[i][j]++;
        }
    }
}
int QueryPoint(int x,int y){
    return sum(x,y)-sum(x-1,y)-sum(x,y-1)+sum(x-1,y-1);
}
int QueryRec(int x1,int y1,int x2,int y2){//询问矩阵时候要注意别写错坐标
    return sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1);
}
int main(){
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++){
        build();
        scanf("%d",&q);
        printf("Case %d:\n",cas);
        while(q--){
            scanf("%d",&type);
            if(!type){
                scanf("%d%d",&x1,&y1);
                x1++,y1++;
                if(!QueryPoint(y1,x1))add(y1,x1);
            }else{
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x1++,y1++,x2++,y2++;
                printf("%d\n",QueryRec(y1,x1,y2,x2));
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值