题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610
题意:在0-8000长的线段里面,按先后次序依次覆盖颜色,求最后每种颜色有多少条
线段树功能:区间覆盖。
分析:区间覆盖后将叶子节点信息取出来O(N)扫一遍即可。
注意:线段长度固定为8000,并不是n,否则无限“Segmentation Fault”。
#pragma comment(linker,"/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <cstdlib> #include <stack> #include <vector> #include <set> #include <map> #define LL long long #define mod 1000000007 #define inf 0x3f3f3f3f #define N 10010 #define FILL(a,b) (memset(a,b,sizeof(a))) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; int col[N<<2]; int cnt[N],num[N]; void Pushdown(int rt) { if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=col[rt]; col[rt]=-1; } } void build(int l,int r,int rt) { col[rt]=-1; if(l==r) { return; } int m=(l+r)>>1; build(lson); build(rson); } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { col[rt]=c; return; } Pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,lson); if(m<R)update(L,R,c,rson); } void query(int l,int r,int rt) { if(l==r) { cnt[l]=col[rt]; return; } Pushdown(rt); int m=(l+r)>>1; query(lson); query(rson); } int main() { int n,m;; int a,b,c; while(scanf("%d",&n)>0) { build(1,8000,1); m=n; while(m--) { scanf("%d%d%d",&a,&b,&c); if(a==b)continue; update(a+1,b,c,1,8000,1); } query(1,8000,1); FILL(num,0); for(int i=1;i<=8000;i++) { while(cnt[i]==cnt[i+1]&&i<8000)i++; if(cnt[i]!=-1) num[cnt[i]]++; } for(int i=0;i<=8000;i++) { if(num[i])printf("%d %d\n",i,num[i]); } puts(""); } }