zoukankan      html  css  js  c++  java
  • 【模板】线段树

    线段树用于维护区间信息,模板使用结构体来表示线段树,这样看起来结构更加清晰,正常使用并不会用结构体。

     1 #include<stdio.h>
     2 #define maxn 100005
     3 #define lll long long
     4 struct node{int l,r;lll sum,laz;};
     5 lll ori[maxn];
     6 struct segt
     7 {
     8     node seg[maxn*6];
     9     lll build(int now)//建立线段树
    10     {
    11         node t = seg[now];
    12         if(t.l==t.r){seg[now].sum=ori[t.l];return seg[now].sum;}
    13         int mid = (t.l+t.r)>>1,lc = now<<1,rc = lc|1;
    14         seg[lc].l = t.l; seg[lc].r = mid;
    15         seg[rc].l = mid+1; seg[rc].r = t.r;
    16         seg[now].sum = build(lc)+build(rc);
    17         return seg[now].sum;
    18     }
    19     void push(int now)//推送懒标记
    20     {
    21         if(seg[now].laz)
    22         {
    23             lll lz = seg[now].laz; seg[now].laz = 0;
    24             seg[now].sum += lz*(seg[now].r-seg[now].l+1);
    25             if(seg[now].l==seg[now].r) return;
    26             seg[now<<1].laz += lz; seg[(now<<1)|1].laz += lz;
    27         }
    28     }
    29     void upd(int now,int l,int r,lll w)//区间修改
    30     {
    31         push(now);
    32         if(seg[now].l>r||seg[now].r<l) return;
    33         if(l<=seg[now].l&&seg[now].r<=r) {seg[now].laz+=w;push(now);return;}
    34         int lc = now<<1,rc = lc|1;
    35         upd(lc,l,r,w); upd(rc,l,r,w);
    36         seg[now].sum = seg[lc].sum + seg[rc].sum;
    37     }
    38     lll que(int now,int l,int r)//区间查询
    39     {
    40         push(now);
    41         if(seg[now].l>r||seg[now].r<l) return 0;
    42         if(l<=seg[now].l&&seg[now].r<=r) return seg[now].sum;
    43         return que(now<<1,l,r) + que((now<<1)|1,l,r);
    44     }
    45 }T;
    46 int n,op;
    47 int main()
    48 {
    49     scanf("%d%d",&n,&op);
    50     int i,flag,p,q; lll w;
    51     for(i=1;i<=n;i++) scanf("%lld",ori+i);
    52     T.seg[1].l = 1; T.seg[1].r= n;
    53     T.build(1);
    54     for(i=1;i<=op;i++)
    55     {
    56         scanf("%d%d%d",&flag,&p,&q);
    57         if(flag==1)
    58         {
    59             scanf("%lld",&w);
    60             T.upd(1,p,q,w); 
    61         }
    62         else
    63         {printf("%lld
    ",T.que(1,p,q));}
    64     } 
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    周赛F题 POJ 1458(最长公共子序列)
    HDU 4720 Naive and Silly Muggles 2013年四川省赛题
    HDU 4716 A Computer Graphics Problem 2013年四川省赛题
    SCU 4440 Rectangle 2015年四川省赛题
    SCU 4436 Easy Math 2015年四川省赛题
    大数模板——六种实现了加减乘除和求余
    HDU 1002 A + B Problem II
    CodeForces 689C  Mike and Chocolate Thieves
    CodeForces 689A -Mike and Cellphone
    CodeForces 595B
  • 原文地址:https://www.cnblogs.com/hzs2000/p/6710785.html
Copyright © 2011-2022 走看看