Count the Colors---zoj1610线段树

题目链接

题意:

求每种颜色有几段线段;

 

模拟数组:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define N 8006
int cnt[N],a[N];
int main()
{
    int n, p, q, c;
    while(scanf("%d", &n) != EOF)
    {
        int Max = 0;
        memset(a, 0, sizeof(a));
        memset(cnt, 0, sizeof(cnt));
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d", &p, &q, &c);
            for(int j=p; j<q; j++)
                a[j] = c+1;
            Max = max(Max, q);
        }
        for(int i=0; i<Max; i++)
        {
            while(i!=0 && a[i]!=0 && a[i]==a[i-1])
                i++;
            if(a[i] != 0)
                cnt[ a[i]-1 ]++;
        }
        for(int i=0; i<N; i++)
        {
            if(cnt[i]!=0)
                printf("%d %d\n", i, cnt[i]);
        }
        printf("\n");
    }
    return 0;
}
View Code
#include<stdio.h>
#include<string.h>
#define N 8005

struct SegTree
{
    int L,R,c;
    int mid()
    {
        return (L+R)>>1;
    }
}a[N*4];

int cnt[N], vis[N];

void BuildSegTree(int r, int L, int R)
{
    a[r].L = L;
    a[r].R = R;
    a[r].c = -1;
    if(L+1==R)//一条线段的两个端点相差1,
        return ;
    BuildSegTree(r*2, L, a[r].mid());
    BuildSegTree(r*2+1, a[r].mid(), R);//题目给的是端点值,对于线段不能用a[r].mid()+1;
}
void Update(int r, int L, int R, int c)
{
    if(a[r].c == c)return ;//如果说这条线段的颜色和要涂的相同,返回;
    if(a[r].L == L && a[r].R == R)
    {
        a[r].c = c;//指定范围内改成颜色c;
        return ;
    }
    if(a[r].c != -1)
    {
        a[2*r].c = a[2*r+1].c = a[r].c;//更新左右子树;
        a[r].c = -1;
    }

    if(R<=a[r].mid())
        Update(2*r, L, R, c);
    else if(L>=a[r].mid())//等于号不能省;原因是这是线段不是点;
        Update(2*r+1, L, R, c);
    else
    {
        Update(2*r, L, a[r].mid(), c);
        Update(2*r+1, a[r].mid(), R, c);
    }
}
void Query(int r, int L, int R)
{
    if(a[r].c != -1)//到达叶子节点;
    {
        if(vis[L] != a[r].c)
            cnt[ a[r].c ]++;
        vis[R] = a[r].c;
        return ;
    }
    if(R-L == 1)
        return ;
    Query(2*r, L, a[r].mid());
    Query(2*r+1, a[r].mid(), R);
}

int main()
{
    int n, p, q, c;
    while(scanf("%d", &n) != EOF)
    {
        memset(cnt, 0, sizeof(cnt));
        memset(vis, -1, sizeof(vis));

        BuildSegTree(1, 0, 8000);

        while(n--)
        {
            scanf("%d %d %d", &p, &q, &c);
            if(p == q)continue;
            Update(1, p, q, c);
        }
        Query(1, 0, 8000);

        for(int i=0; i<N; i++)
        {
            if(cnt[i] != 0)
                printf("%d %d\n", i, cnt[i]);
        }
        printf("\n");
    }
    return 0;
}
View Code

 

posted @ 2015-07-31 17:42  西瓜不懂柠檬的酸  Views(189)  Comments(0Edit  收藏  举报
levels of contents