zoukankan      html  css  js  c++  java
  • 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
    ", i, cnt[i]);
            }
            printf("
    ");
        }
        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
    ", i, cnt[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    设计模式之桥接模式
    设计模式之观察者模式
    设计模式之装饰者模式
    设计模式之适配器模式
    2 深入分析 Java IO的工作机制(二)
    struts2常用标签使用说明
    JDK环境变量配置
    Oracle恢复删除数据 && connect by 树形结构查询
    Spring和Hibernate集成配置
    Struts2中重定向和请求转发配置
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4692806.html
Copyright © 2011-2022 走看看