Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can see at last.
Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces: All the numbers are in the range [0, 8000], and they are all integers. Input may contain several data set, process to the end of file.
If some color can't be seen, you shouldn't print it. Print a blank line after every dataset.
1 1 0 2
Author: Standlove Source: ZOJ Monthly, May 2003 |
题意:在一条线段上画颜色,画n次,每次使x1到 x2区间颜色变为 c。求表面上能看到的颜色种类和该颜色的段数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 8005
#define MAXN 40005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std;
struct tree
{
int l,r,color;
}tree[maxn<<2],TREE[maxn<<2];
int n,num;
int ans[maxn];
void pushdown(int rt)
{
if (tree[rt].color>-1)
{
tree[rt<<1].color=tree[rt].color;
tree[rt<<1|1].color=tree[rt].color;
tree[rt].color=-1;
}
}
void build(int rt,int l,int r)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].color=-1;
if (l==r)return ;
int mid=(tree[rt].l+tree[rt].r)>>1;
build(lson);
build(rson);
}
void update(int rt,int l,int r,int color)
{
if (l<=tree[rt].l&&tree[rt].r<=r)
{
tree[rt].color=color;
return ;
}
pushdown(rt);
int mid=(tree[rt].l+tree[rt].r)>>1;
if(mid>=r) update(rt<<1,l,r,color);
else if (mid<l) update(rt<<1|1,l,r,color);
else{
update(lson,color);
update(rson,color);
}
}
void Count(int rt,int l,int r)
{
if (l==tree[rt].l&&tree[rt].r==r&&tree[rt].color>-1)
{
TREE[num].l=l;
TREE[num].r=r;
TREE[num++].color=tree[rt].color;
return ;
}
if (l==r) return ;
int mid=(tree[rt].l+tree[rt].r)>>1;
if (mid>=r) Count(rt<<1,l,r);
else if(mid<l) Count(rt<<1|1,l,r);
else{
Count(lson);
Count(rson);
}
}
int main()
{
int i,j;
int l,r,color;
while (~sf(n))
{
num=0;
build(1,1,maxn); //注意是maxn,不是n!!!
FRL(i,0,n)
{
sfff(l,r,color);
update(1,l+1,r,color);
}
Count(1,1,maxn); //注意是maxn,不是n!!!
mem(ans,0);
ans[TREE[0].color]++;
FRL(i,1,num)
{
//前后两个线段颜色不一样或者不相邻
if (TREE[i].color!=TREE[i-1].color||TREE[i].l-1>TREE[i-1].r)
ans[TREE[i].color]++;
}
FRL(i,0,maxn)
{
if (ans[i])
pf("%d %d\n",i,ans[i]);
}
pf("\n");
}
return 0;
}
/*
5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3
4
0 1 1
3 4 1
1 3 2
1 3 1
6
0 1 0
1 2 1
2 3 1
1 2 0
2 3 0
1 2 1
*/