poj 2777 Count Color 线段树

来源:互联网 发布:韩国人和日本人知乎 编辑:程序博客网 时间:2024/04/27 23:05

题目链接:poj 2777

        给定一段区间,对该区间进行染色,询问操作

  染色操作对特定的区间进行染色

  询问操作求对应区间中节点颜色的种类总数

  线段树操作,因为颜色种类总数一共就30种,因此可以在节点中用用二进制表示区间中有的颜色。

/****************************************************** * File Name:   2777.cpp * Author:      kojimai * Creater Time:2014年08月30日 星期六 00时25分57秒 ******************************************************/#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;struct seg{int l,r,c;//c用二进制来表示当前段中颜色的种类bool flag;//表示当前段被涂上同样的颜色}node[500005];void buildtree(int l,int r,int num){node[num].l=l;node[num].r=r;node[num].flag=true;node[num].c=1;if(l==r)return;int mid=(l+r)/2;buildtree(l,mid,num*2);buildtree(mid+1,r,num*2+1);}int Count(int x){int ret=0;while(x){if(x%2==1)ret++;x/=2;}return ret;}void update(int l,int r,int c,int num){if(node[num].l>=l&&node[num].r<=r){node[num].c=(1<<(c-1));node[num].flag=true;return;}if(node[num].flag){node[num*2].flag=true;node[num*2+1].flag=true;node[num*2].c=node[num].c;node[num*2+1].c=node[num].c;node[num].flag=false;}int mid=(node[num].l+node[num].r)/2;if(mid>=r)update(l,r,c,num*2);else if(mid<l)update(l,r,c,num*2+1);else{update(l,mid,c,num*2);update(mid+1,r,c,num*2+1);}node[num].c=node[num*2].c|node[num*2+1].c;return;}int query(int l,int r,int num){//cout<<"l="<<l<<" r="<<r<<" nodel="<<node[num].l<<" noder="<<node[num].r<<" c="<<node[num].c<<endl;if(node[num].l==l&&node[num].r==r){return node[num].c;}if(node[num].flag){node[num*2].flag=node[num*2+1].flag=true;node[num*2].c=node[num].c;node[num*2+1].c=node[num].c;node[num].flag=false;}int mid=(node[num].l+node[num].r)/2;if(mid>=r)return query(l,r,num*2);else if(mid<l)return query(l,r,num*2+1);else{return query(l,mid,num*2)|query(mid+1,r,num*2+1);}}int main(){int L,t,q;while(~scanf("%d%d%d",&L,&t,&q)){buildtree(1,L,1);char ch;int x,y,z;while(q--){getchar();scanf("%c",&ch);//cout<<ch<<endl;if(ch=='C'){scanf("%d%d%d",&x,&y,&z);if(x>y)swap(x,y);update(x,y,z,1);}else{scanf("%d%d",&x,&y);if(x>y)swap(x,y);int sum=query(x,y,1);cout<<Count(sum)<<endl;}}}return 0;}


0 0
原创粉丝点击