hdu6183 Color it

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\leq a\leq x$ and $y1\leq b\leq y2$, then the color $c$ should be counted.

3 : exit.

Solution

可以视为三维数点问题

对于每一次询问限制为:修改时间在询问之前,修改横坐标在询问横坐标之前,修改的纵坐标在指定区间

CDQ分治

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
int n,tot,opt;
long long ans[150050];
struct Q{
    int opt,a,b,c,id;
    bool operator <(const Q &z)const{return a<z.a;}
}que[150050],ql[150050],qr[150050];
struct SGT{
    long long val;
}tr[4000005];
inline int read(){
    int w=0,f=1;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return w*f;
}
int calc(long long x){return x?x%2+calc(x>>1):0;}
void pushup(int i){tr[i].val=tr[i<<1].val|tr[i<<1|1].val;}
void update(int i,int l,int r,int p,int v,int opt){
    if(l==r){
        if(opt)tr[i].val|=(1ll<<v);
        else tr[i].val=0;
        return;
    }
    int mid=l+r>>1;
    if(p<=mid)update(i<<1,l,mid,p,v,opt);
    else update(i<<1|1,mid+1,r,p,v,opt);
    pushup(i);
}
long long query(int i,int l,int r,int L,int R){
    if(L<=l&&r<=R)return tr[i].val;
    int mid=l+r>>1;
    long long ret=0;
    if(L<=mid)ret|=query(i<<1,l,mid,L,R);
    if(R>mid)ret|=query(i<<1|1,mid+1,r,L,R);
    return ret;
}
void cdq(int l,int r){
    if(l==r)return;
    int mid=l+r>>1,cntl=0,cntr=0,pos=1;
    cdq(l,mid),cdq(mid+1,r);
    for(int i=l;i<=mid;i++)ql[++cntl]=que[i];
    for(int i=mid+1;i<=r;i++)qr[++cntr]=que[i];
    sort(ql+1,ql+cntl+1),sort(qr+1,qr+cntr+1);
    for(int i=1;i<=cntr;i++){
        if(qr[i].opt==2){
            while(pos<=cntl&&ql[pos].a<=qr[i].a){
                if(ql[pos].opt==1)update(1,1,1000000,ql[pos].b,ql[pos].c,1);
                ++pos;
            }
            ans[qr[i].id]|=query(1,1,1000000,qr[i].b,qr[i].c);
        }
    }
    for(int i=1;i<pos;i++)update(1,1,1000000,ql[i].b,ql[i].c,0);
}
int main(){
    opt=read();
    for(;true;){
        for(;true;){
            opt=read();
            if(opt==1||opt==2)++tot,que[tot]=(Q){opt,read(),read(),read(),tot};
            else break;
        }
        cdq(1,tot);
        for(int i=1;i<=tot;i++)if(que[i].opt==2)printf("%d\n",calc(ans[i])),ans[i]=0;
        tot=0;
        if(opt==3)break;
    }
    return 0;
}
Color it

 

posted @ 2021-02-04 10:32  QDK_Storm  阅读(77)  评论(0编辑  收藏  举报