hdu6183(线段树动态开点)

来源:互联网 发布:源生活网络超市 编辑:程序博客网 时间:2024/05/29 17:41

链接:点击打开链接

题意:有三种操作,分别为:

0 清除矩阵中所有颜色

1 x y c 在(x,y)点涂上c颜色

2 x y1 y2 询问左上角为(1,y1),右上角为(x,y2)的矩阵中含有的颜色种数

代码:

#include <stack>#include <string>#include <vector>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int siz=1000005;int id=0;int rt[105],ll[siz],rr[siz],val[siz];void build(int &s,int p,int L,int R,int x){    if(s==0){                                   //主要就是动态开点,需要时再建立节点        s=(++id);                               //并不会建一颗完整的线段树        val[s]=x;                               //剩下的跟静态建线段树是一样的    }    if(val[s]>x)    val[s]=x;    if(L==R)    return;    int m=(L+R)>>1;    if(p<=m)    build(ll[s],p,L,m,x);    else    build(rr[s],p,m+1,R,x);}void query(int p,int L,int R,int l,int r,int x,int &pos){    if(l<=L&&R<=r){                             //查询时最好也不要遍历整颗树        if(val[p]<=x)                           //已经小于就不再继续遍历        pos=1;        return;    }    if(pos)    return;    int m=(L+R)>>1;    if(l<=m&&ll[p]!=0)    query(ll[p],L,m,l,r,x,pos);    if(r>m&&rr[p]!=0)    query(rr[p],m+1,R,l,r,x,pos);               //整体思路就是建50颗线段树}                                               //按y轴建树,单点更新,求区间最小的x值int main(){                                     //rt[i]表示i颜色线段树的根节点    int i,c,x,y1,y2,op,ans,pos;                 //ll[i]表示编号i节点的左儿子    memset(rt,0,sizeof(rt));                    //rr[i]表示编号i节点的右儿子    memset(ll,0,sizeof(ll));    memset(rr,0,sizeof(rr));    while(scanf("%d",&op)&&op!=3){        if(op==0){            for(i=0;i<=50;i++)            rt[i]=0;            for(i=0;i<=id;i++)            ll[i]=rr[i]=0;            id=0;        }        else if(op==1){            scanf("%d%d%d",&x,&y1,&c);            build(rt[c],y1,1,1000000,x);        }        else if(op==2){            scanf("%d%d%d",&x,&y1,&y2);            ans=0;            for(i=0;i<=50;i++){                pos=0;                query(rt[i],1,1000000,y1,y2,x,pos);                if(pos==1)                ans++;            }            printf("%d\n",ans);        }    }    return 0;}

阅读全文
0 0