题目链接:http://poj.org/problem?id=2777
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 40402 | Accepted: 12186 |
Description
Input
Output
Sample Input
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Output
2 1
Source
题目大意:一个长度为L的区间,最多有T种颜色,并且有O种操作,接下去有o行。
一共就两种操作:1、C a b c:表示的是将【a,b】这个区间染成颜色c。 2、P a b :表示的是询问【a,b】这个区间有多少种颜色。
解题思路:这个题目需要注意的是不能一直更新到最下面,就更新到符合的区间即可,否则会超时。
详见代码。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; struct node { int l,r; int num; } s[400010]; int vis[35]; void InitTree(int l,int r,int k) { s[k].l=l; s[k].r=r; s[k].num=1; int mid=(l+r)/2; if (l==r) return ; InitTree(l,mid,2*k); InitTree(mid+1,r,2*k+1); } void UpdataTree(int l,int r,int c,int k) { if(s[k].l==l&&s[k].r==r) { s[k].num=c; return; } if (s[k].num==c) return; if (s[k].num!=-1)//如果所查询的区间不是多种颜色 { s[2*k].num=s[k].num;//更新区间的颜色 s[2*k+1].num=s[k].num; s[k].num=-1;//-1表示该区间有多种颜色 } int mid=(s[k].l+s[k].r)/2; if (l>mid) UpdataTree(l,r,c,2*k+1); else if (r<=mid) UpdataTree(l,r,c,2*k); else { UpdataTree(l,mid,c,2*k); UpdataTree(mid+1,r,c,2*k+1); } } void SearchTree(int l,int r,int k) { if (s[k].num!=-1) { vis[s[k].num]=1; return; } int mid=(s[k].l+s[k].r)/2; if (r<=mid) SearchTree(l,r,2*k); else if (l>mid) SearchTree(l,r,2*k+1); else { SearchTree(l,mid,2*k); SearchTree(mid+1,r,2*k+1); } } int main() { int l,t,o,ans; while (~scanf("%d%d%d",&l,&t,&o)) { InitTree(1,l,1); while (o--) { char ch; int a,b,c; getchar(); scanf("%c",&ch); if (ch=='C') { scanf("%d%d%d",&a,&b,&c); if (a>b) swap(a,b); UpdataTree(a,b,c,1); } else { scanf("%d%d",&a,&b); if (a>b) swap(a,b); memset(vis,0,sizeof(vis)); SearchTree(a,b,1); ans=0; for (int i=1; i<=t; i++) if (vis[i]==1) ans++; printf ("%d\n",ans); } } } return 0; }
poj 2777 Count Color(线段树+染色问题)
原文:http://blog.csdn.net/qiqi_skystar/article/details/50364489