zoukankan      html  css  js  c++  java
  • 树状数组与普通线段树模板

    树状数组(区间修改,单点求值)

     1 const int N=500005;
     2 int a[N],c[N],n,m;
     3 
     4 void modify(int x,int y)
     5 {
     6     for(;x<=n;x+=x&(-x)) c[x]+=y;
     7 }
     8 
     9 int query(int x)
    10 {
    11     int res=0;
    12     for(;x;x-=x&(-x)) res+=c[x];
    13     return res;
    14 }
    15 
    16 int main()
    17 {
    18     scanf("%d%d",&n,&m);
    19     FOR(i,1,n) scanf("%d",&a[i]);
    20     while(m--)
    21     {
    22         int opt;scanf("%d",&opt);
    23         if(opt==1)
    24         {
    25             int x,y,k;
    26             scanf("%d%d%d",&x,&y,&k);
    27             modify(x,k);
    28             modify(y+1,-k);
    29         }
    30         else
    31         {
    32             int x;scanf("%d",&x);
    33             printf("%d
    ",query(x)+a[x]);
    34         }
    35     }
    36     return 0;
    37 }

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

    const int N=100005;
    struct tree
    {
        int l,r;
        ll sum,add;
        #define l(x) t[x].l
        #define r(x) t[x].r
        #define sum(x) t[x].sum
        #define add(x) t[x].add
    }t[N<<2];
    int a[N],n,m;
    
    void build(int p,int l,int r)
    {
        l(p)=l,r(p)=r;
        if(l==r) {sum(p)=a[l];return;}
        int mid=(l+r)>>1,q=p<<1;
        build(q,l,mid),build(q|1,mid+1,r);
        sum(p)=sum(q)+sum(q|1);
    }
    
    void pushdown(int p)
    {
        if(!add(p)) return;
        int q=p<<1;
        sum(q)+=add(p)*(r(q)-l(q)+1);
        sum(q|1)+=add(p)*(r(q|1)-l(q|1)+1);
        add(q)+=add(p);
        add(q|1)+=add(p);
        add(p)=0;
    }
    
    void modify(int p,int l,int r,int k)
    {
        if(l<=l(p)&&r>=r(p))
        {
            sum(p)+=(ll)k*(r(p)-l(p)+1);
            add(p)+=k;
            return;
        }
        pushdown(p);
        int mid=(l(p)+r(p))>>1,q=p<<1;
        if(l<=mid) modify(q,l,r,k);
        if(r>mid) modify(q|1,l,r,k);
        sum(p)=sum(q)+sum(q|1);
    }
    
    ll query(int p,int l,int r)
    {
        if(l<=l(p) && r>=r(p)) return sum(p);
        pushdown(p);
        int mid=(l(p)+r(p))>>1,q=p<<1;
        ll val=0;
        if(l<=mid) val+=query(q,l,r);
        if(r>mid) val+=query(q|1,l,r);
        return val;
    }
    
    int main()
    {
        freopen("hh.out","w",stdout);
        scanf("%d%d",&n,&m);
        FOR(i,1,n) scanf("%d",&a[i]);
        build(1,1,n);
        while(m--)
        {
            int opt;scanf("%d",&opt);
            if(opt==1)
            {
                int x,y,k;
                scanf("%d%d%d",&x,&y,&k);
                modify(1,x,y,k);
            }
            else
            {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%lld
    ",query(1,x,y));
            }
        }
        return 0;
    }

     动态开点(权值线段树)

     1 struct tree
     2 {
     3     int lc,rc;
     4     int dat;
     5 }t[N<<1];
     6 int root,tot;
     7 
     8 int build()
     9 {
    10     t[++tot].lc=t[tot].rc=t[tot].dat=0;
    11     return tot;
    12 }
    13 void insert(int p,int l,int r,int val,int k)
    14 {
    15     if(l==r){t[p].dat+=k;return;}
    16     int mid=(l+r)>>1;
    17     if(val<=mid)
    18     {
    19         if(!t[p].lc) t[p].lc=build();
    20         insert(t[p].lc,l,mid,val,k);
    21     }
    22     else
    23     {
    24         if(!t[p].rc) t[p].rc=build();
    25         insert(t[p].rc,mid+1,r,val,k);
    26     }
    27     t[p].dat=t[t[p].lc].dat+t[t[p].rc].val;
    28 }
    29 
    30 int main()
    31 {
    32     root=build();
    33     insert(root,1,n,val,k);
    34 }

    线段树合并(相同权值)

     1 int merge(int p,int q,int l,int r)
     2 {
     3     if(!p) return q;
     4     if(!q) return p;
     5     if(l==r) {t[p].dat+=t[q].dat;return p;}
     6     int mid=(l+r)>>1;
     7     t[p].lc=merge(t[p].lc,t[q].lc,l,mid);
     8     t[p].rc=merge(t[p].rc,t[q].rc,mid+1,r);
     9     t[p].dat=t[t[p].lc].dat+t[t[p].rc].dat;
    10     return p;
    11 }
  • 相关阅读:
    集合的代数运算
    集合的代数运算
    poj1639 Picnic Planning,K度限制生成树
    C/C++学习站点资源
    Mustache 使用心得总结
    PostgreSQL服务端监听设置及client连接方法
    【线性规划与网络流24题】汽车加油行驶问题 分层图
    linux系统下信号具体解释2
    【数据结构】栈-数组的实现
    EJB究竟是什么,真的那么神奇吗??
  • 原文地址:https://www.cnblogs.com/universeplayer/p/10539473.html
Copyright © 2011-2022 走看看