POJ 2777 线段树

来源:互联网 发布:温度数据采集板 编辑:程序博客网 时间:2024/04/26 12:19

题目大意:
有一个长度为L的木板,在上面可以涂t种颜色,有p个操作,操作可以是将a-b涂成c的颜色,也可以是询问a-b有多少种不同的颜色,对每次询问输出答案。

#include<iostream>#include<stdio.h>#include<string.h>#define maxn 100000using namespace std;struct TREE{    int left,right;    int color;}t[maxn*4+10];bool vis[40]; //记录颜色是否出现过 //建树 void buildtree(int root,int left,int right){    t[root].left=left;    t[root].right=right;    t[root].color=1;  //初始化,对于底层节点表示该点的颜色为1;对于非底层节点则表示该节点对应的所有颜色均为1     if(left==right)        return;    int mid=(right+left)/2;    buildtree(root*2,left,mid);    buildtree(root*2+1,mid+1,right);}//更新 //t[root]==0 表示该节点对应的区间颜色不单一 //t[root]!=0 表示该节点对应的区间颜色单一,且为t[root]的值 //始终牢记线段树的更新是从根节点开始的 即从上向下更新,直到更新到想要的区间才停止更新 void update(int root,int left,int right,int color){ //更新时注意保留原始的更新区间     if(t[root].left==left&&t[root].right==right){ //如果某节点的区间刚好等于想要更新的区间         t[root].color=color;                      //将该点的颜色进行更新,并不再向下更新         return;    }    if(t[root].color==color) return;  //如果某节点的颜色更好等于想要更新的颜色,不再向下更新(优化,不写也能过)     if(t[root].color){                //如果该区间颜色单一         t[root*2].color=t[root].color;  //更新下面节点的颜色         t[root*2+1].color=t[root].color;        t[root].color=0;              //该点的颜色设置为不单一     }    int mid=(t[root].left+t[root].right)/2;    if(right<=mid) update(root*2,left,right,color);  //别写成update(root*2,left,mid+1,color) 这样的话是把左边的都更新了     else if(left>mid) update(root*2+1,left,right,color);    else{        update(root*2,left,mid,color);            //这两个区间合并起来是left-right         update(root*2+1,mid+1,right,color);     }} //询问 void query(int root,int begin,int end){  //询问时注意保留原始的询问区间         if(t[root].color){    //如果该点对应的区间下为单一颜色             vis[t[root].color]=1;   //标记该颜色出现过             return;                //不继续向下找了         }    int mid=(t[root].left+t[root].right)/2;    if(end<=mid) query(root*2,begin,end);    else if(begin>mid) query(root*2+1,begin,end);    else{        query(root*2,begin,mid);query(root*2+1,mid+1,end);    }   }int main(){    int l,T,p,i,j;    while(scanf("%d%d%d",&l,&T,&p)!=EOF){        buildtree(1,1,l);        for(j=1;j<=p;j++){            getchar(); //注意             char ch;            scanf("%c",&ch);            int a,b,c;            scanf("%d%d",&a,&b);            if (a>b)                    swap(a,b);            if(ch=='P'){                memset(vis,0,sizeof(vis));                int sum=0;                          query(1,a,b);                for(i=1;i<=T;i++)                    if(vis[i]==1){                        sum++;                    }                                       printf("%d\n",sum);            }            if(ch=='C'){                scanf("%d",&c);                update(1,a,b,c);            }        }    }    return 0;}