zoj 1610(线段树染色问题)

题意:染色后求一段区间上各个颜色的段数

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
struct node
{
    int l,r,w,f;
}tree[8005*4+5];
int a,b,x,num[8005],last;
void build(int l,int r,int k)
{
    tree[k].l=l;tree[k].r=r;
    tree[k].w=-1;
    tree[k].f=-1;
    if(l==r)
        return ;
    int mid=(l+r)/2;
    build(l,mid,k*2);
    build(mid+1,r,k*2+1);
}
void down(int k)
{
    tree[k*2].w=tree[k].f;
    tree[k*2+1].w=tree[k].f;
    tree[k*2].f=tree[k].f;
    tree[k*2+1].f=tree[k].f;
    tree[k].f=-1;
}
void change(int k)
{
    if(tree[k].l>=a&&tree[k].r<=b)
    {
        tree[k].w=x;
        tree[k].f=x;
        return ;
    }
    if(tree[k].f!=-1) down(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(mid>=a)change(k*2);
    if(mid<b)change(k*2+1);
    if(tree[k*2].w==tree[k*2+1].w)
        tree[k].w=tree[k*2].w;
    else
        tree[k].w=-1;
}
void query(int k)
{
    if(tree[k].w!=-1||tree[k].l==tree[k].r)
    {
        if(tree[k].w!=last)
        {
            num[tree[k].w]++;
        }
        last=tree[k].w;
        return ;
    }
    if(tree[k].f!=-1)down(k);
    int mid=(tree[k].r+tree[k].l)/2;
    query(k*2);
    query(k*2+1);
}
int main()
{
    int n;
    while(cin>>n)
    {
        last=-1;
        build(1,8000,1);
        memset(num,0,sizeof(num));
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&x);
            a++;
            change(1);
        }
        query(1);
        for(int i=0;i<=8000;i++)
        {
            if(num[i]!=0)
                printf("%d %d\n",i,num[i]);
        }
        puts("");
    }
}

猜你喜欢

转载自blog.csdn.net/prometheus_97/article/details/78045881
今日推荐