题目大意:
在一条线上涂颜色,以前某一段的颜色可能被后来的覆盖。
你的任务是数数最后你可以看见多少种颜色
输入:x1 x2 c
x1和x2分别代表段的两端,c代表颜色
解题思路:
线段树问题
代码如下:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxes=20001;
int temp;
struct node
{
int left;
int right;
int kind;
}segtree[maxes];
int color[8001];
void creat_tree(int n,int l,int r)
{
segtree[n].left=l;
segtree[n].right=r;
segtree[n].kind=-1;
if(l+1==r) return;
int mid=(l+r)>>1;
creat_tree(n*2,l,mid);
creat_tree(n*2+1,mid,r);
}
void insert_tree(int n,int l,int r,int c)
{
if(l==r) return;
if(segtree[n].kind==c) return;
if(l<=segtree[n].left&&segtree[n].right<=r)
{
segtree[n].kind=c;
return;
}
if(segtree[n].kind>=0)
{
segtree[n*2].kind=segtree[n].kind;
segtree[n*2+1].kind=segtree[n].kind;
segtree[n].kind=-2;
}
int mid=(segtree[n].left+segtree[n].right)>>1;
if(r<=mid)
{
insert_tree(n*2,l,r,c);
}
else if(l>=mid)
{
insert_tree(n*2+1,l,r,c);
}
else
{
insert_tree(n*2,l,mid,c);
insert_tree(n*2+1,mid,r,c);
}
}
void count(int n)
{
if(segtree[n].kind!=-1&&segtree[n].kind!=-2)
{
if(segtree[n].kind!=temp)
{
color[segtree[n].kind]++;
temp=segtree[n].kind;
}
return;
}
if(segtree[n].left+1!=segtree[n].right)
{
count(n*2);
count(n*2+1);
}
else
temp=-1;
}
int main()
{
int i,t,a,b,c;
while(scanf("%d",&t)!=EOF)
{
creat_tree(1,0,8000);
while(t--)
{
scanf("%d%d%d",&a,&b,&c);
insert_tree(1,a,b,c);
}
temp=-1;
memset(color,0,sizeof(color));
count(1);
for(i=0;i<=8000;i++)
{
if(color[i])
printf("%d %d\n",i,color[i]);
}
printf("\n");
}
return 0;
}