zoj1610

题目大意:

在一条线上涂颜色,以前某一段的颜色可能被后来的覆盖。
你的任务是数数最后你可以看见多少种颜色
输入: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值