2018.07.08 hdu6183 Color it(线段树)

Color it
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Problem Description
Do you like painting? Little D doesn’t like painting, especially messy color paintings. Now Little B is painting. To prevent him from drawing messy painting, Little D asks you to write a program to maintain following operations. The specific format of these operations is as follows.
0 : clear all the points.
1 x y c : add a point which color is c at point (x,y).
2 x y1 y2 : count how many different colors in the square (1,y1) and (x,y2). That is to say, if there is a point (a,b) colored c, that 1≤a≤x and y1≤b≤y2, then the color c should be counted.
3 : exit.
Input
The input contains many lines.
Each line contains a operation. It may be ‘0’, ‘1 x y c’ ( 1≤x,y≤106,0≤c≤50 ), ‘2 x y1 y2’ (1≤x,y1,y2≤106 ) or ‘3’.
x,y,c,y1,y2 are all integers.
Assume the last operation is 3 and it appears only once.
There are at most 150000 continuous operations of operation 1 and operation 2.
There are at most 10 operation 0.
Output
For each operation 2, output an integer means the answer .
Sample Input
0
1 1000000 1000000 50
1 1000000 999999 0
1 1000000 999999 0
1 1000000 1000000 49
2 1000000 1000000 1000000
2 1000000 1 1000000
0
1 1 1 1
2 1 1 2
1 1 2 2
2 1 1 2
1 2 2 2
2 1 1 2
1 2 1 3
2 2 1 2
2 10 1 2
2 10 2 2
0
1 1 1 1
2 1 1 1
1 1 2 1
2 1 1 2
1 2 2 1
2 1 1 2
1 2 1 1
2 2 1 2
2 10 1 2
2 10 2 2
3
Sample Output
2
3
1
2
2
3
3
1
1
1
1
1
1
1
Source
2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)
Recommend
liuyiding | We have carefully selected several similar problems for you: 6297 6296 6295 6294 6293

这是一道经典的线段树简单题,对于操作0,直接手动清零(你可以直接当做这道题有多组数据来看),然后就是相对来说思维难度略高一点的另外两个操作(操作3略)。

先思考一个问题,这道题如何维护答案?

观察数据范围可以发现, c c 的取值范围很小,只有[0,50],这不禁让我们想到对于每一种颜色建一颗线段树,然后每次询问时我们跑一个 O50logn O ( 50 l o g n ) 来查询,看看时限和数据范围应该没啥问题。所以怎么维护这种信息呢?

我们知道,所有点的 x x 坐标都满足1xi,这样的话,我们可以维护每一个 y y 坐标上所对应的x坐标的最小值。然后查询时就看在当前 y y 坐标范围内的最小值是否小于x就行了。

还剩了一个问题:空间的处理。这个可以使用动态开点的方法,这样你实际使用的空间只与修改次数有关。(不过我每次写动态开点的问题感觉线段树格式写的都很丑)

代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define Node 2500010
#define n 1000005
#define inf 0x3f3f3f3f
using namespace std;
int rt[60],son[Node<<2][2],minn[Node<<2],cnt=0;
inline void init(){
    memset(rt,0,sizeof(rt));
    cnt=0;
    son[0][1]=son[0][0]=0;
    minn[0]=inf;
}
inline void pushup(int p){minn[p]=min(minn[son[p][0]],minn[son[p][1]]);}
inline void update(int &p,int l,int r,int y,int x){
    if(!p){
        p=++cnt;
        son[p][0]=son[p][1]=0;
        minn[p]=x;
    }
    if(l==r){
        minn[p]=min(minn[p],x);
        return;
    }
    int mid=l+r>>1;
    if(y<=mid)update(son[p][0],l,mid,y,x);
    else update(son[p][1],mid+1,r,y,x);
    pushup(p);
}
inline int query(int p,int l,int r,int ql,int qr){
    if(!p)return inf;
    if(ql<=l&&r<=qr)return minn[p];
    int mid=l+r>>1;
    if(qr<=mid)return query(son[p][0],l,mid,ql,qr);
    if(ql>mid)return query(son[p][1],mid+1,r,ql,qr);
    return min(query(son[p][0],l,mid,ql,mid),query(son[p][1],mid+1,r,mid+1,qr));
}
int main(){
    init();
    int op;
    while(~scanf("%d",&op)){
        if(op==3)break;
        switch(op){
            case 0:{
                init();
                break;
            }
            case 1:{
                int qx,qy,c;
                scanf("%d%d%d",&qx,&qy,&c);
                update(rt[c],1,n,qy,qx);
                break;
            }
            default:{
                int x,ql,qr,ans=0;
                scanf("%d%d%d",&x,&ql,&qr);
                for(int i=0;i<=50;++i)ans+=(query(rt[i],1,n,ql,qr)<=x);
                printf("%d\n",ans);
                break;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值