ZOJ 1610 Count the Colors(線段樹)
阿新 • • 發佈:2018-12-15
題意:
題意:給一個區間,有n次染色操作,每次將[x1, x2]染為c,求最後每種顏色各有多少線段可以看到。
分析:
根原來稍有些不同。不過還是一般的套路。就是得注意兩個地方,一個是用tmp表示之前一段的區間顏色。另一個是當詢問操作的過程中進行到l==r的時候記得把tmp再修改回-1.
#include<bits/stdc++.h> using namespace std; int n,tmp; const int maxn=8100; int tree[maxn<<2]; int ans[maxn]; void update(int i){ if(tree[i]==-1) return; tree[i<<1]=tree[i<<1|1]=tree[i]; tree[i]=-1; } void change(int tl,int tr,int i,int l,int r,int c){ if(tl>r||tr<l) return; if(tl<=l&&r<=tr){ tree[i]=c; return ; } update(i); int mid=l+r>>1; change(tl,tr,i<<1,l,mid,c); change(tl,tr,i<<1|1,mid+1,r,c); } void query(int l,int r,int i){ if(tree[i]!=-1){ if(tree[i]!=tmp){ ans[tree[i]]++; } tmp=tree[i]; return; } if(l==r){ tmp=-1; //記得這塊。 return; } int mid=l+r>>1; query(l,mid,i<<1); query(mid+1,r,i<<1|1); } int main(){ while(scanf("%d",&n)!=EOF){ memset(tree,-1,sizeof tree); while(n--){ int x,y,c; scanf("%d%d%d",&x,&y,&c); change(x+1,y,1,1,8000,c); } tmp=-1; //tmp儲存之前一段的顏色。 memset(ans,0,sizeof ans); query(1,8000,1); for(int i=0;i<=8000;i++){ if(ans[i]) printf("%d %d\n",i,ans[i]); } puts(""); } return 0; }