题意:给一个区间,有n次染色操作,每次将[x1, x2]染为c,求最后每种颜色各有多少线段可以看到。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<set> #include<vector> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-10 typedef long long LL; const int MAXN = 1e5+5; const int mod = 998244353; LL st[MAXN << 2]; int vis[MAXN]; void pushdown(int o) { if(st[o] != -1) { st[o << 1] = st[o]; st[o << 1 | 1] = st[o]; st[o] = -1; return; } } void update(int o,int l,int r,int ql,int qr,int c) { if(ql <= l && r <= qr) { st[o] = c; return; } else { if(st[o] != c){ pushdown(o); int m = (l + r) >> 1; if(ql <= m) update(o << 1,l,m,ql,qr,c); if(m + 1 <= qr) update(o << 1 | 1,m + 1,r,ql,qr,c); } else return; } } int last; void query(int o,int l,int r) { if(l == r) { if(st[o] != -1 && st[o] != last) vis[st[o]]++; last = st[o]; return; } pushdown(o); int m = (l + r) >> 1; query(o << 1,l,m); query(o << 1 | 1,m + 1,r); } int main() { int n; while(~scanf("%d",&n)) { memset(st,-1,sizeof st); while(n--) { int x,y,c; scanf("%d %d %d",&x,&y,&c); update(1,1,8000,x + 1,y,c); } memset(vis,0,sizeof vis); last = -1; query(1,1,8000); for(int i = 0; i <= 8000; i++) if(vis[i]) printf("%d %d ",i,vis[i]); printf(" "); } }