做法:在udate之后可以直接把线段树上的信息映射到一个数组上考虑
#include<cstdio> #include<cstring> #define left l,m,x<<1 #define right m+1,r,x<<1|1 const int LMT=16002; int cov[LMT<<2],seg[LMT],ans[LMT]; //映射法 void init(void) { memset(cov,-1,sizeof(cov)); memset(seg,-1,sizeof(seg)); memset(ans,0,sizeof(ans)); } void cut(int x) { if(cov[x]!=-1) { cov[x<<1]=cov[x<<1|1]=cov[x]; cov[x]=-1; } } void update(int co,int L,int R,int l,int r,int x) { if(L<=l&&r<=R) { cov[x]=co; return ; } cut(x); int m=(l+r)>>1; if(L<=m)update(co,L,R,left); if(R>m)update(co,L,R,right); } void query(int l,int r,int x)//线段树射到区间上 { if(cov[x]!=-1) { int i=l; for(;i<=r;i++)seg[i]=cov[x]; return; } if(l==r)return; int m=(l+r)>>1; query(left); query(right); } int main(void) { int n,l,r,co,i,j; while(~scanf("%d",&n)) { init(); for(i=1;i<=n;i++) { scanf("%d%d%d",&l,&r,&co); l++;r++; l<<=1;r<<=1; update(co,l,r,1,LMT-1,1); } query(1,LMT-1,1); for(int i=1;i<LMT;) if(seg[i]!=-1) { j=i;ans[seg[i]]++; while(j<LMT&&seg[j]==seg[i])j++; i=j; } else i++; for( i=0;i<=8000;i++) if(ans[i])printf("%d %d\n",i,ans[i]); printf("\n"); } return 0; }