codevs p1082线段树 区间修改

原创 2016年05月30日 22:10:48

lazy表示的是给节点o的lc和rc加减的数字

也是codevs p1082的题解


#include <bits/stdc++.h>
#define lc (o<<1)
#define rc (lc|1)
#define m ((l+r)>>1)
using namespace std;
const int MAXN = 200000 + 5;
typedef long long LL;
LL lazy[MAXN<<2],sum[MAXN<<2],a[MAXN];
int in()
{
    LL c=getchar(),x=0;
    while(!isdigit(c))c=getchar();
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x;
}
inline void up(int o,int l,int r)
{
    sum[o]=0;
    if(l==r)sum[o]=a[r];
    else sum[o]=sum[lc]+sum[rc];
    if(lazy[o])sum[o]+=lazy[o]*(r-l+1);
}
void update(int o,int l,int r,int cl,int cr,int cv)
{
    if(cl<=l && r<=cr)
    {
        lazy[o]+=cv;
    }
    else
    {
        if(cl<=m)update(lc,l,m,cl,cr,cv);
        if(m+1<=cr)update(rc,m+1,r,cl,cr,cv);
    }
    up(o,l,r);
}
LL query(int o,int l,int r,int ql,int qr,LL add)
{
    LL ans=0;
    if(ql<=l && r<=qr)
    {
        return sum[o]+add*(r-l+1);
    }
    if(ql<=m)ans+=query(lc,l,m,ql,qr,add+lazy[o]);
    if(m+1<=qr)ans+=query(rc,m+1,r,ql,qr,add+lazy[o]);
    return ans;
}
void build(int o,int l,int r)
{
    if(l==r)
    {
        sum[o]=a[r];
        return;
    }
    build(lc,l,m);
    build(rc,m+1,r);
    up(o,l,r);
}
int main()
{
    int n=in();
    for(int i=1;i<=n;i++)a[i]=in();
    build(1,1,n);
    /*
    printf("\nbug\n\n");
    for(int i=1;i<=n;i++)printf("%d ",query(1,1,n,i,i,0));
    printf("\nbug\n\n");
    */
    int q=in();
    while(q--)
    {
        int type=in();
        if(type==1)
        {
            int x=in(),y=in(),z=in();
            update(1,1,n,x,y,z);
        }
        else
        {
            int x=in(),y=in();
            printf("%lld\n",query(1,1,n,x,y,0));
        }
        /*
        printf("\nbug\n\n");
        for(int i=1;i<=2*n-1;i++)printf("%lld ",lazy[i]);
        printf("\n");
        for(int i=1;i<=n;i++)printf("%lld ",query(1,1,n,i,i,0));
        printf("\nbug\n\n");
        */
    }
    return 0;
}
版权声明:咩

线段树区间修改 lazy标记 大法

#include #include #define maxn 100000 + 10 #define Lson L, mid, rt
  • DoJintian
  • DoJintian
  • 2015年05月03日 10:39
  • 3523

线段树模板:点修改,区间修改

最近在看《算法竞赛入门经典训练指南》, 感觉以前的想法几乎完全是错的,模板并不一定能直接套。 最近在看线段树,才知道线段树每个节点的附加信息才是重头戏,因此完全套模板是不可行的。但是思想方法可以借鉴,...
  • qq_33929112
  • qq_33929112
  • 2016年10月10日 17:00
  • 570

hihocoder 1078 线段树的区间修改 (线段树 区间更新 模板)

hihocoder 1078 线段树的区间修改 (线段树 区间更新 模板)
  • Tc_To_Top
  • Tc_To_Top
  • 2016年04月01日 13:11
  • 2282

非递归线段树区间修改区间求和的两种实现(以POJ 3468为例)

非递归线段树实现区间修改区间求和的两种方法(以 POJ 3468 为例)
  • u012891242
  • u012891242
  • 2015年04月07日 08:37
  • 1599

【洛谷】线段树 树状数组区间修改区间查询

在做一道整体二分的题目的时候遇到了这种区间修改区间查询的树状数组,感觉用起来手感不错就拿来了。证明的话,那其实不重要,会用就好了 #include #include #include #define...
  • pbihao
  • pbihao
  • 2016年12月06日 22:10
  • 132

线段树(区间修改,区间求和)

lzay标记,注意query和updata的时候都需要push,并且push的位置不同#include #include #include using namespace std; const ...
  • lanxuan365
  • lanxuan365
  • 2015年08月15日 17:36
  • 285

线段树区间修改+区间查询

大致思路:线段树的区间修改要比点修改难想一点。主要是多了一个延迟标记,目的是为了降低复杂度。但在询问的时候还需要把延迟标记逐个下放,还要更新原来的点,这就导致很难想了。 主要记住顺序: 要求区间修改...
  • SCaryon
  • SCaryon
  • 2017年08月04日 20:45
  • 670

hdu 4348 可持久化线段树(区间和

链接:戳这里 To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java...
  • libin66
  • libin66
  • 2016年08月15日 14:24
  • 508

HDU 1698 Just a Hook(线段树区间修改)

题目链接:点击打开链接 题意: 输入一个n表示一段长度为n的区间,有n个编号为1~n的点,初始值全部为1。 有q个操作, 每个操作有3个数:l,r,v表示将区间l~r的所有元素修改为v。 求经过q次修...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2016年01月01日 20:24
  • 1730

zkw线段树修正 标记上升

今天才发现统计的力量很坑爹,同时发现了我写线段树的漏洞。 首先说我自己的问题,线段树最后一层的第一个节点不能用,但我以前用了而且一直没出问题,这次涉及区间修改才出现问题。 然后是统计的力量,里面关...
  • huyuncong
  • huyuncong
  • 2011年10月04日 21:03
  • 1485
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:codevs p1082线段树 区间修改
举报原因:
原因补充:

(最多只允许输入30个字)