• hdu 5023(线段树区间染色,统计区间内颜色个数)


    题目描述:区间染色问题,统计给定区间内有多少种颜色?

    线段树模板的核心是对标记的处理

    可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点

     Lazy操作减少修改的次数(在查询或者修改的过程中才更新标记对节点val值的影响,每次更新val值只更新到当前要查询或者修改的节点,最底层的标记以下的节点的val值应该是没有被更新过)

    Pushdown向下传递标记和修改子节点的val值,

    Pushup修改递归访问的节点的val值(更新父节点的val值)

    大区间和小区间的先后修改顺序。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    //线段树
    //区间染色
    const int maxN = 1000010;
    struct node
    {
        int lt, rt, val, turn;
    }tree[4*maxN];
    int a[30];
    int t=0;
    //向下更新
    void pushDown(int id)
    {
        if (tree[id].turn != 0)
        {
            tree[id<<1].turn = tree[id<<1].val = tree[id].turn;
            tree[id<<1|1].turn = tree[id<<1|1].val = tree[id].turn;
            tree[id].turn = 0;
        }
    }
    
    //向上更新
    void pushUp(int id)
    {
        if (tree[id<<1].val == tree[id<<1|1].val)
            tree[id].val = tree[id<<1].val;
        else
            tree[id].val = 0;
    }
    
    //建立线段树
    void build(int lt, int rt, int id)
    {
        tree[id].lt = lt;
        tree[id].rt = rt;
        tree[id].val = 2;//每段的初值,根据题目要求
        tree[id].turn = 2;
        if (lt == rt)
        {
            //tree[id].turn = ??;
            tree[id].turn=2;
            return;
        }
        int mid = (lt+rt)>>1;
        build(lt, mid, id<<1);
        build(mid+1, rt, id<<1|1);
    }
    
    //更改每段的值,多用于染色
    void change(int lt, int rt, int id, int col)
    {
        if(lt <= tree[id].lt && rt >= tree[id].rt)
        {
            tree[id].val = tree[id].turn = col;
            return;
        }
        pushDown(id);
        int mid = (tree[id].lt+tree[id].rt)>>1;
        if (lt <= mid)
            change(lt, rt, id<<1, col);
        if (rt > mid)
            change(lt, rt, id<<1|1, col);
        pushUp(id);
    }
    
    void query(int lt, int rt, int id)
    {
        if (lt > tree[id].rt || rt < tree[id].lt)
            return;
        if (tree[id].val != 0)
        {
            //operator;
            int ok=0;
            for(int i=0;i<t;i++)
                {
                  if(a[i]==tree[id].val)
                     ok=1;
                }
             if(ok==0)
              a[t++]=tree[id].val;
            return;
        }
        query(lt, rt, id<<1);
        query(lt, rt, id<<1|1);
    }
    int main()
    {
       // freopen("test.txt","r",stdin);
        int n,m;
        while(~scanf("%d%d",&n,&m) && (n!=0 || m!=0) )
        {
            build(1,n,1);
            while(m--)
            {
                char str[5];
                scanf("%s",str);
                //printf("%s
    ",str);
                if(str[0]=='P')
                {
                    int l,r,turn,root=1;
                    scanf("%d%d%d",&l,&r,&turn);
                    change(l,r,1,turn);
                 }
                else
                {
                    int l,r;
                    t=0;
                    scanf("%d%d",&l,&r);
                    query(l,r,1);
                    sort(a,a+t);
                    for(int i=0;i<t;i++)
                    {
                        if(i)
                            printf(" ");
                        printf("%d",a[i]);
                    }
                    printf("
    ");
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    好代码收藏
    JVM
    关于Redis
    记录ok6410 使用ov9650摄像头的过程
    记录一下在uyuv 转 planar yuv420 的做法
    mini2440 使用的mkyaffs2image 工具的源码
    hi3516a imx178 uboot 默认启动参数
    记录ok6410 使用fast150u 无线网卡的过程 其中部分内容为转载 没有修改
    ubuntu建立tftp服务器有两种方式
    转载hi3516 sd 只读解决
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4867253.html
Copyright © 2020-2023  润新知