ZOJ1610 Count the Colors
给出每一线段的颜色,存在颜色覆盖,要求最后能看到的每种颜色及其段数
线段树区间更新~
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=10014; struct node { int l; int r; int color; }segTree[maxn*4]; int color[maxn]; int tmp; void build (int i,int l,int r) { segTree[i].l=l; segTree[i].r=r; segTree[i].color=-1; if (l+1==r) return; int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid,r); } void update (int i,int l,int r,int c) { if (l==r) return; if (segTree[i].color==c) return; if (l<=segTree[i].l&&r>=segTree[i].r) { segTree[i].color=c; return; } if (segTree[i].color>=0) { //存在颜色,往下更新 segTree[i<<1].color=segTree[i].color; segTree[i<<1|1].color=segTree[i].color; segTree[i].color=-2;//表示有多种颜色 } int mid=(segTree[i].l+segTree[i].r)>>1; if (r<=mid) update(i<<1,l,r,c); else if (l>mid) update(i<<1|1,l,r,c); else { update(i<<1,l,mid,c); update(i<<1|1,mid,r,c); } segTree[i].color=-2; } void cnt (int i) { //统计各颜色的段数 if (segTree[i].color==-1) { tmp=-1; return; } if (segTree[i].color!=-2) { if (segTree[i].color!=tmp) { //tmp存的是前一段的颜色 color[segTree[i].color]++; tmp=segTree[i].color; } return; } if (segTree[i].l+1!=segTree[i].r) { cnt(i<<1); cnt(i<<1|1); } } int main () { int n,a,b,c; int Max; while (~scanf("%d",&n)) { build (1,0,8000); Max=0; while (n--) { scanf ("%d %d %d",&a,&b,&c); update(1,a,b,c); if (c>Max) Max=c; } tmp=-1; memset (color,0,sizeof(color)); cnt(1); for (int i=0;i<=Max;i++) if (color[i]) printf ("%d %d\n",i,color[i]); printf ("\n"); } return 0; }