CF444C DZY Loves Colors

DZY喜欢色彩,他热爱绘画。

在一个多姿多彩的日子里,DZY得到了一个彩色的缎带,它由N个单元组成(从左到右从1到n编号)。色带的第ii个单位的最初颜色是i。虽然颜色足够丰富,但我们仍然认为每个单元的颜色数量最初是0。

DZY热衷于绘画,我们知道。他拿起一把彩色X笔,用它在缎带上画一条线。在这种情况下,他就绘制了一段连续的单元。想象一下,单位i被涂之前颜色是Y。被涂之后时,单元的颜色变为X,令单位的颜色增加了∣X−Y∣。 DZY想要执行M个操作,每个操作可以是下列操作之一:

1、将区间[L,R]内单元绘制为颜色X。

2、询问[L,R]之间的单位颜色的总和(包括两者)。

我们用线段树维护这一段的答案和这段颜色是否一样,如果一样是什么颜色

每次我们修改时候对相同的颜色段修改,不相同的颜色段递归暴力修改

对于一次区间覆盖,只会产生两个新的端点,所以只会暴力(O(n+2m))

复杂度(O(mlogn))

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define N 100000
#define zrt k << 1
#define yrt k << 1 | 1
using namespace std;
int n,m;
struct node
{
    int tag,c;
    long long su,at;
    node ()
    {
        at = su = c = tag = 0;
    }
};
int myabs(int x)
{
    if (x > 0)
        return x;
    return -x;
}
struct Seg
{
    node s[N * 4 + 5];
    node upd(node x,node y)
    {
        node k;
        if (x.c == y.c)
            k.c = x.c;
        k.su = x.su + y.su;
        return k;
    }
    void build(int k,int l,int r)
    {
        if (l == r)
        {
            s[k].c = l;
            s[k].su = 0LL;
            return;
        }
        int mid = l + r >> 1;
        build(zrt,l,mid);
        build(yrt,mid + 1,r);
        s[k] = upd(s[zrt],s[yrt]);
    }
    void pushdown(int k,int l,int r,int mid)
    {
        if (!s[k].tag && !s[k].at)
            return;
        if (s[k].tag)
        {
            s[zrt].c = s[k].tag;
            s[yrt].c = s[k].tag;
            s[zrt].tag = s[k].tag;
            s[yrt].tag = s[k].tag;
        }
        if (s[k].at)
        {
            s[zrt].su += (long long)(mid - l + 1) * s[k].at;
            s[yrt].su += (long long)(r - mid) * s[k].at;
            s[zrt].su += s[k].at;
            s[yrt].su += s[k].at;
        }
        s[k].tag = s[k].at = 0;
    }
    void change(int k,int l,int r,int x,int y,int z)
    {
        if (l >= x && r <= y && s[k].c)
        {
            s[k].su += (long long)myabs(z - s[k].c) * (long long)(r - l + 1);
            s[k].c = z;
            s[k].tag = z;
            s[k].at += (long long)myabs(z - s[k].c);
            return;
        }
        int mid = l + r >> 1;
        pushdown(k,l,r,mid);
        if (x > mid)
            change(yrt,mid + 1,r,x,y,z);
        else
            if (y <= mid)
                change(zrt,l,mid,x,y,z);
            else
                change(zrt,l,mid,x,y,z),change(yrt,mid + 1,r,x,y,z);
        s[k] = upd(s[zrt],s[yrt]);
    }
    node query(int k,int l,int r,int x,int y)
    {
        if (l >= x && r <= y)
            return s[k];
        int mid = l + r >> 1;
        pushdown(k,l,r,mid);
        if (x > mid)
            return query(yrt,mid + 1,r,x,y);
        else
            if (y <= mid)
                return query(zrt,l,mid,x,y);
            else
                return upd(query(zrt,l,mid,x,y),query(yrt,mid + 1,r,x,y));
    }
}tree;
int main()
{
    scanf("%d%d",&n,&m);
    tree.build(1,1,n);
    int opt,l,r,z;
    for (int i = 1;i <= m;i++)
    {
        scanf("%d%d%d",&opt,&l,&r);
        if (opt == 1)
        {
            scanf("%d",&z);
            tree.change(1,1,n,l,r,z);
        }
        else
            printf("%lld
",tree.query(1,1,n,l,r).su);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sdlang/p/13068045.html