<html>

题意:

一段区间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 424C. Magic Formulas (异或规律)

链接:http://codeforces.com/problemset/problem/424/C 题目: People in the Tomskaya region like magic fo...

Codeforces 444C(线段树)

区间颜色不一致就更新究竟。否则lazy标记 #include #include #include #include using namespace std; #define lc l,m,index...

CodeForces 631C Report(找规律)

题目链接:【CodeForces 631C】 长度是n的数列。m个次訪问,两种操作:1、t=1,将数列1~r从小到大排序。2、t=2,将数列1~r从大到小排列。输出最后得到的数列 假设i>j&&r...

Codeforces 460C Present(二分)

题目链接:Codeforces 460C Present 题目大意:有n盆花,能够浇m次水。每次浇水的范围为w。被浇到水的花长高1米,问说能够使最矮的花的最高值是多少 解题思路:二分答案。...

codeforces 414 c

题意: 给出一个长度为n

Codeforces 479C Exams(贪心)

题目链接:Codeforces 479C Exams 题目大意:期末考试了,有个人希望尽快考全然部的科目。于是和每一个科任老师单独沟通。最后每一个科任老师愿意给额 外给定一个时间单独给她考试。...

CodeForces 140C 贪心+优先队列

Description 如今来做雪人,每一个雪人由三个不同大小的雪球构成:一个大的。一个中等的,一个小的。如今有 n 个雪球半径分别为 r1, r2, ..., rn. 为了做雪人。三个雪球的大小必须...

codeforces-757-【B、C思维】

题目链接:点击打开链接 A. Gotta Catch Em' All! time limit per test 1 second memory limit per te...

Codeforces 466C Number of Ways(高效)

题目链接:Codeforces 466C Number of Ways 题目大意:给定一个序列。要求分成三段,每段和同样,问有多少种拆分方法。 解题思路:将所有前缀和为sum3的位置所有记...

Codeforces 444C DZY Loves Colors 线段树区间更新

// Codeforces 444C DZY Loves Colors 线段树区间更新 // 题目链接: // http://codeforces.com/problemset/pr...
  • 微博
    微信
    QQ
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多仅仅同意输入30个字)

posted @ 2017-08-12 18:06  yfceshi  阅读(127)  评论(0编辑  收藏  举报