CodeForces 444C DZY Loves Colors

题意:

一段区间a一开始是1、2、3、4……n这样的  每次1操作可以将[l,r]覆盖成x  同时得到abs(a[i]-x)的价值  2操作查询[l,r]的价值

思路:

线段树  又是一道加深线段树理解的题

操作2是简单的求和  线段树基本操作  难点在操作1

用cov表示该区间的值(如果为0说明是混合区间)  用val表示该区间的价值和

那么在更新时就不仅仅是找到 tree[i].l==l&&tree[i].r==r 就停止了  而是继续向下递归  直到一段区间的cov>0才结束

之所以这么做是因为要将x覆盖到之前覆盖过的连续的区间(其实就是将以前混合的区间合并成一个)  这是更新val所必须的

但如此做了我们会发现val只计算到了更新过的位置  无法将这次更新down下去  那么就需要设置一个lazy标志

lazy记录该区间还没有被down下去的价值

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 101000
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
typedef __int64 ll;

int n,m;
struct node
{
    int l,r,cov;
    ll val,lazy;
}tree[N*4];
ll ans;

int abs(int x)
{
    if(x<0) return -x;
    return x;
}

void up(int i)
{
    tree[i].val=tree[L(i)].val+tree[R(i)].val;
}

void down(int i)
{
    if(tree[i].cov)
    {
        tree[L(i)].cov=tree[i].cov;
        tree[R(i)].cov=tree[i].cov;
        tree[i].cov=0;
    }
    if(tree[i].lazy)
    {
        tree[L(i)].lazy+=tree[i].lazy;
        tree[L(i)].val+=tree[i].lazy*(tree[L(i)].r-tree[L(i)].l+1);
        tree[R(i)].lazy+=tree[i].lazy;
        tree[R(i)].val+=tree[i].lazy*(tree[R(i)].r-tree[R(i)].l+1);
        tree[i].lazy=0;
    }
}

void init(int l,int r,int i)
{
    tree[i].l=l; tree[i].r=r; tree[i].val=tree[i].lazy=0;
    if(l==r)
    {
        tree[i].cov=l;
        return ;
    }
    int mid=(l+r)/2;
    init(l,mid,L(i));
    init(mid+1,r,R(i));
}

void solve(int i,int key)
{
    if(tree[i].cov)
    {
        tree[i].lazy+=abs(key-tree[i].cov);
        tree[i].val+=(ll)(abs(key-tree[i].cov))*(tree[i].r-tree[i].l+1);
        tree[i].cov=key;
        return ;
    }
    else
    {
        down(i);
        solve(L(i),key);
        solve(R(i),key);
        up(i);
    }
    tree[i].cov=key;
}

void update(int l,int r,int i,int key)
{
    if(tree[i].l==l&&tree[i].r==r)
    {
        solve(i,key);
        return ;
    }
    down(i);
    int mid=(tree[i].l+tree[i].r)/2;
    if(r<=mid) update(l,r,L(i),key);
    else if(l>mid) update(l,r,R(i),key);
    else
    {
        update(l,mid,L(i),key);
        update(mid+1,r,R(i),key);
    }
    up(i);
}

void query(int l,int r,int i)
{
    if(tree[i].l==l&&tree[i].r==r)
    {
        ans+=tree[i].val;
        return ;
    }
    down(i);
    int mid=(tree[i].l+tree[i].r)/2;
    if(r<=mid) query(l,r,L(i));
    else if(l>mid) query(l,r,R(i));
    else
    {
        query(l,mid,L(i));
        query(mid+1,r,R(i));
    }
    up(i);
}

int main()
{
    int p,l,r,w;
    scanf("%d%d",&n,&m);
    init(1,n,1);
    while(m--)
    {
        scanf("%d%d%d",&p,&l,&r);
        if(p==1)
        {
            scanf("%d",&w);
            update(l,r,1,w);
        }
        else
        {
            ans=0;
            query(l,r,1);
            printf("%I64d\n",ans);
        }
    }
    return 0;
}

CodeForces 444C DZY Loves Colors

时间: 2024-10-07 06:33:49

CodeForces 444C DZY Loves Colors的相关文章

Codeforces 444C DZY Loves Colors(线段树)

题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是修改区间上l到r上面德值为x,2是询问l到r区间总的修改值. 解题思路:线段树模板题. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn = 5*1e5; typedef long lo

Codeforces 444C DZY Loves Colors 水线段树

题目链接:点击打开链接 水.. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <math.h> #include <set> #include <vector> #include <map> using namespace std; #define ll long long #defi

codeforces - 444c DZY Loves Colors(线段树+染色)

C. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output DZY loves colors, and he enjoys painting. On a colorful day, DZY gets a colorful ribbon, which consists of n units (they

CodeForces 444C. DZY Loves Physics(枚举+水题)

转载请注明出处:http://blog.csdn.net/u012860063/article/details/37509207 题目链接:http://codeforces.com/contest/445/problem/C DZY Loves Physics DZY loves Physics, and he enjoys calculating density. Almost everything has density, even a graph. We define the densi

CodeForces 445E DZY Loves Colors

DZY Loves Colors Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 445E64-bit integer IO format: %I64d      Java class name: (Any) DZY loves colors, and he enjoys painting. On a colorful day, DZY gets a

Cf 444C DZY Loves Colors(线段树)

DZY loves colors, and he enjoys painting. On a colorful day, DZY gets a colorful ribbon, which consists of n units (they are numbered from 1 to n from left to right). The color of thei-th unit of the ribbon is i at first. It is colorful enough, but w

Cf 444C DZY Loves Colors(段树)

DZY loves colors, and he enjoys painting. On a colorful day, DZY gets a colorful ribbon, which consists of n units (they are numbered from 1 to n from left to right). The color of thei-th unit of the ribbon is i at first. It is colorful enough, but w

codeforces 444 C. DZY Loves Colors(线段树)

题目大意: 1 l r x操作 讲 [l,r]上的节点涂成x颜色,并且每个节点的值都加上 |y-x| y为涂之前的颜色 2 l r  操作,求出[l,r]上的和. 思路分析: 如果一个区间为相同的颜色.那么我们才可以合并操作. 所以我们之前找相同的区间就好. 但是问题是如何合并操作. 那么我们定义一个val  表示这个区间每个位置上应该加上的值. pushdown 的时候这个值是可以相加的. #include <cstdio> #include <iostream> #includ

Codeforces Round #254 DZY Loves Colors

题意:输入n, m ; 有n给位置, 初始时第i个位置的color为i, colorfulness为0. 有m次操作,一种是把成段的区域color更新为x, 对于更新的区域,每个位置(令第i个位置未更新前颜色为color[i])的colorfulness增加|color[i] -x|; 另一种操作是询问一段区间[L,R]输出该区间的colorfulness总和. 1 #include <iostream> 2 #include <cstdio> 3 #include <cst