Count the Colors
题意:每次对区间染色,注意不染端点,然后问最后每种颜色有多少段。
题解:用线段树维护每个区间的颜色信息,然后因为不染端点,因此如果染 0 → 4 0\rightarrow4 0→4,只会染 4 4 4个区间那么我们将左端点加一即可。其它就是经典线段树 l a z y lazy lazy标记下放了。
代码
#include<bits/stdc++.h>
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
using namespace std;
//0 1 2 3 4
//|4|4|4|4|
//|1|1|1|4|
//|1|1|1|2|
//|2|2|1|2|
//|3|3|1|2|
const int N = 8010;
int tr[N << 2], ans[N],color[N];
void pushdown(int rt)
{
if(tr[rt] != -1) {
tr[rt << 1] = tr[rt];
tr[rt << 1 | 1] = tr[rt];
tr[rt] = -1;
}
}
void update(int rt,int l,int r,int x,int y,int z)
{
if(x <= l && r <= y) {
tr[rt] = z;
return;
}
int mid = l + r >> 1;
pushdown(rt);
if(x <= mid) update(rt << 1, l, mid, x, y, z);
if(y > mid) update(rt << 1 | 1, mid + 1, r, x, y, z);
}
void query(int rt,int l,int r,int x,int y)
{
if(x <= l && r <= y) {
if(tr[rt] != -1) {
for(int i = l; i <= r; ++i) {
color[i] = tr[rt];
}
return;
}
}
if(l == r) return;
int mid = l + r >> 1;
if(x <= mid)
query(rt << 1, l, mid, x, y);
if(y > mid)
query(rt << 1 | 1, mid + 1, r, x, y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
ios::sync_with_stdio(false); cin.tie(0);
int n,x,y,z;
while(cin >> n) {
memset(tr, -1, sizeof tr);
memset(ans, 0, sizeof ans);
memset(color,-1,sizeof color);
while(n--) {
cin >> x >> y >> z;
if(x >= y) continue;
update(1,1,N,x + 1,y,z);
}
query(1,1,N,1,N);
for(int i = 1; i < N; ++i) {
if(color[i] == -1) continue;
int c = color[i];
ans[c]++;
for(; i < N && color[i] == c; ++i);
i--;
}
for(int i = 0; i < N; ++i) {
if(ans[i]) cout << i << ' ' << ans[i] << endl;
}
cout << endl;
}
return 0;
}