• 线段树区间染色+注意事项


    题目链接:https://vjudge.net/contest/269834#problem/E

    具体思路:用线段树储存每个区间的颜色,然后再打一个染色的标记,注意最后统计的时候,相邻区间的不注意的话会被算成两种。如果按照我一开始的思路的打,(1,4)这个区间,(5,8)这个区间,如果(1,4)的颜色和(5,7)的颜色相同,但是如果(5,8)是一个混色的时候,这个时候会被统计成两个颜色,其实是只有一种颜色,这个地方注意下。

    AC代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<iomanip>
    #include<cmath>
    #include<stack>
    #include<map>
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    using namespace std;
    # define inf 0x3f3f3f3f
    # define ll long long
    # define maxn 5000000+1000
    # define lson l,m,rt<<1
    # define rson m+1,r,rt<<1|1
    int a[maxn];
    int col[maxn];
    map<int,int>q;
    int ans[maxn];
    int t;
    void up(int rt)
    {
        if(col[rt<<1]==-1||col[rt<<1|1]==-1)
        {
            col[rt]=-1;
            return ;
        }
        if(a[rt<<1]!=a[rt<<1|1])
        {
            col[rt]=-1;
            return ;
        }
        a[rt]=a[rt<<1];
        col[rt]=1;
    }
    void down(int rt)
    {
        if(col[rt]!=-1)
        {
            col[rt<<1]=col[rt<<1|1]=col[rt];
            a[rt<<1|1]=a[rt<<1]=a[rt];
            col[rt]=-1;
        }
    }
    void update(int L,int R,int p,int l,int r,int rt)
    {
        if(L<=l&&R>=r)
        {
            a[rt]=p;
            col[rt]=1;
            return ;
        }
        down(rt);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,p,lson);
        if(R>m)update(L,R,p,rson);
        up(rt);
    }
    void query(int l,int r,int rt)
    {
        if(l==r)
        {
            ans[++t]=a[rt];//记录最底层的颜色
            return ;
        }
        down(rt);
        int m=(l+r)>>1;
        query(lson);
        query(rson);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            t=0;
            memset(a,-1,sizeof(a));
            memset(col,-1,sizeof(col));
            memset(ans,-1,sizeof(ans));
            q.clear();
            int t1,t2,t3;
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d%d",&t1,&t2,&t3);
                t1++;
                update(t1,t2,t3,1,8001,1);
            }
            query(1,8010,1);
            q[ans[1]]++;
            int num=0;
            for(int i=2; i<=t; i++)
            {
                if(ans[i]!=ans[i-1])//相邻的颜色相同的话,颜色算一种
                {
                    q[ans[i]]++;
                }
            }
            for(int i=0; i<=8001; i++)
            {
                if(q[i]!=0)
                {
                    printf("%d %d
    ",i,q[i]);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    20150629_Andriod_06_插入_删除_弹出式操作数据
    20150626_Andriod_02_ListView2_列表与详细信息
    Andriod 字符串数组里加入字符串元素
    20150625_Andriod_02_ListView2_多条目显示_选中
    20150625_Andriod_01_ListView1_条目选中
    Android开发中完全退出程序的三种方法
    Python中的单例模式的几种实现方式的及优化
    jdk与jre
    页面跳转
    用for循环创建对象
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262825.html
Copyright © 2020-2023  润新知