HDU5997 【线段树】

思路:

用vector存一下各种颜色的区间,每次处理颜色的区间,相同颜色不需要更新。区间最多1e6个没错,但是随着颜色的更替区间只会越来越少。

维护区间左右两端的颜色,lazy一下。

区间合并的时候 sum= sum_left + sum_right , 如果左儿子的区间右边和右儿子的区间左边颜色相同 sum--。

复杂度:don't know;

#include
using namespace std;
const int N=1e5+10;

struct Seg{
    int Sum;
    int Lazy;
    int Left,Right;
    int Left_Color,Right_Color;
}q[N*4];

struct asd{
    int Left,Right;
};
vectoreg[1000000+10];
int col[N];

void Pushdown(int num)
{
    if(q[num].Lazy==-1) return;
    q[num<<1].Lazy=q[num<<1|1].Lazy=q[num].Lazy;
    q[num<<1].Sum=q[num<<1|1].Sum=1;
    q[num<<1].Left_Color=q[num<<1].Right_Color=q[num].Lazy;
    q[num<<1|1].Left_Color=q[num<<1|1].Right_Color=q[num].Lazy;
    q[num].Lazy=-1;
}

void Build(int num,int Left,int Right)
{
    q[num].Left=Left;q[num].Right=Right;q[num].Lazy=-1;
    if(Left == Right){
        q[num].Sum=1;
        q[num].Left_Color=q[num].Right_Color=col[Left];
        return;
    }
    int Mid=(Left+Right)>>1;
    Build(num<<1,Left,Mid);
    Build(num<<1|1,Mid+1,Right);
    q[num].Left_Color=q[num<<1].Left_Color;
    q[num].Right_Color=q[num<<1|1].Right_Color;
    if(q[num<<1].Right_Color == q[num<<1|1].Left_Color)
        q[num].Sum=q[num<<1].Sum+q[num<<1|1].Sum-1;
    else
        q[num].Sum=q[num<<1].Sum+q[num<<1|1].Sum;
}

int Query(int num,int Left,int Right)
{
    if(q[num].Left>=Left && q[num].Right<=Right) return q[num].Sum;
    Pushdown(num);

    int Mid=(q[num].Left+q[num].Right)>>1;
    if(Mid>=Right)
        return Query(num<<1,Left,Right);
    else if(Mid>1;
    if(Mid>=Right)
        Update(num<<1,Left,Right,Color);
    else if(Mid


转载于:https://www.cnblogs.com/keyboarder-zsq/p/6777487.html

你可能感兴趣的:(HDU5997 【线段树】)