poj2777Count color(线段树)

来源:互联网 发布:绵阳长虹网络公司地址 编辑:程序博客网 时间:2024/04/26 00:06
题目大意:给你一个长度为n的线段(n<1000000),还有t种颜料(m<30)。有以下两种操作:

1.C a b c :将从a到b的线段涂上c色;

2.P a b:询问从a到b的线段上有多少种颜色。

#include<stdio.h>#include<string.h>#define maxn 100010struct node{int l,r;//线段树区间int mid;//线段树区间中间值int mark;//}p[maxn<<2];int v[32];void build(int id,int l,int r){p[id].l=l;p[id].r=r;p[id].mid=(l+r)>>1;p[id].mark=1;if(l==r) return;build(2*id,l,p[id].mid);build(2*id+1,p[id].mid+1,r);}void update(int id,int l,int r,int val){if(p[id].l==l&&p[id].r==r){p[id].mark=val;return;}if(p[id].mark==val) return;if(p[id].mark!=0){p[id*2].mark=p[id].mark;p[id*2+1].mark=p[id].mark;p[id].mark=0;}if(p[id].mid>=r) update(2*id,l,r,val);else if(p[id].mid<l) update(id*2+1,l,r,val);else{update(id*2,l,p[id].mid,val);update(id*2+1,p[id].mid+1,r,val);}}void query(int id,int l,int r){if(p[id].mark!=0){v[p[id].mark]=1;return;}if(p[id].mid>=r) query(id*2,l,r);else if(p[id].mid<l) query(id*2+1,l,r);else{query(id*2,l,p[id].mid);query(id*2+1,p[id].mid+1,r);}}int main(){int n,m,b,c,d,i,t,tmp,count;char str[5];scanf("%d%d%d",&n,&m,&t);build(1,1,n);for(int j=0;j<t;j++){scanf("%s%d%d",str,&b,&c);if(b>c){tmp=b;b=c;c=tmp;}if(str[0]=='C'){scanf("%d",&d);update(1,b,c,d);}else{memset(v,0,sizeof(v));query(1,b,c);count=0;for(i=1;i<=m;i++)if(v[i]) count++;printf("%d\n",count);}}return 0;}