链接https://vjudge.net/contest/66989#problem/F
坑爹的线段树,一直用区间更新做,做了半天一点眉目都没有,只好搜题解,感觉好堕落,经常不会做就搜题解,以后一定要慢慢克服
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 const int maxn=8010; ll value[maxn<<2],vis[maxn<<2]; void pushdown(int rt)//向下更新 { if(value[rt]!=-1) { value[rt<<1]=value[rt<<1|1]=value[rt];//只要向下更新 value[rt]=-1; } } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R)//区间更新 { value[rt]=c; return ; } if(value[rt]==c)return ; if(value[rt]!=-1)pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,ls); if(R>m)update(L,R,c,rs); } void query(int l,int r,int rt) { if(value[rt]>=0)//也有可能是l==r { for(int i=l;i<=r;i++) vis[i]=value[rt];//vis【i】记录i处的颜色 return ; } if(l!=r&&value[rt]==-1) { int m=(l+r)>>1; query(ls); query(rs); } } int main() { int n,ans[8005]; while(~scanf("%d",&n)){ memset(ans,0,sizeof(ans)); memset(vis,-1,sizeof(vis)); memset(value,-1,sizeof(value));//因为0也算一种颜色,所以初始化-1 for(int i=1;i<=n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a+1,b,c,1,8000,1);//不能用0到8000处理 } query(1,8000,1); int i=1; while(i<maxn){ int color=vis[i],j=i+1; if(vis[i]==-1){i++;continue;}//没有颜色 while(vis[j]!=-1&&vis[j]==color&&j<maxn)j++;//向前推进直到下一个颜色出现 ans[color]++; i=j; } for(int i=0;i<=8000;i++) if(ans[i]) printf("%d %d ",i,ans[i]); printf(" "); } return 0; }