zoukankan      html  css  js  c++  java
  • 区间查询区间维护(线段树)

    传送门:

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <sstream>
    #include <cstdlib>
    #include <algorithm>
    #include <iostream>
    #include <set>
    #include <map>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    using namespace std;
    #define ll long long
    #define re register
    #define mp make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define P pair<int,int>
    const int N=1e6+10;
    void read(ll &a)
    {
        int d=1;
        char ch;
        a=0;
        while(ch=getchar(),!isdigit(ch))
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),isdigit(ch))
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    void write(ll x)
    {
        if(x<0)
            putchar(45),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    ll ans[N<<1],a[N],tag[N<<1];
    ll ls(ll i){return i<<1;}///左儿子
    ll rs(ll i){return i<<1|1;}///右儿子
    void push_up(ll p){ans[p]=ans[ls(p)]+ans[rs(p)];}///区间合并
    void built(ll p,ll l,ll r)
    {
        if(l==r)
        {
            ans[p]=a[l];
            return;
        }
        ll mid=(l+r)>>1;
        built(ls(p),l,mid);
        built(rs(p),mid+1,r);
        push_up(p);///回溯时做区间合并
    }
    void f(ll p,ll l,ll r,ll k)
    {
        tag[p]+=k;
        ans[p]+=(r-l+1)*k;
    }
    void push_down(ll p,ll l,ll r)
    {
        ll mid=(l+r)>>1;
        f(ls(p),l,mid,tag[p]);///将父节点所带的值加到子区间去
        f(rs(p),mid+1,r,tag[p]);
        tag[p]=0;///然后父节点的值归0
    }
    void update(ll nl,ll nr,ll l,ll r,ll p,ll k)
    {
        if(nl<=l&&r<=nr)///包含整个区间,直接加就完事
        {
            ans[p]+=(r-l+1)*k;
            tag[p]+=k;
            return;
        }
        push_down(p,l,r);///将该父节点的值放入子区间
        ll mid=(l+r)>>1;
        if(nl<=mid)
            update(nl,nr,l,mid,ls(p),k);
        if(nr>mid)
            update(nl,nr,mid+1,r,rs(p),k);
        push_up(p);///合并区间
    }
    ll query(ll nl,ll nr,ll l,ll r,ll p)
    {
        ll res=0;
        if(nl<=l&&r<=nr)
            return ans[p];
        ll mid=(l+r)>>1;
        push_down(p,l,r);
        if(nl<=mid)
            res+=query(nl,nr,l,mid,ls(p));
        if(nr>mid)
            res+=query(nl,nr,mid+1,r,rs(p));
        return res;
    }
    int main()
    {
        //freopen("out.txt","w",stdout);
        ll n,T;
        read(n);
        read(T);
        for(re ll i=1;i<=n;i++)
            read(a[i]);
        built(1,1,n);
        while(T--)
        {
            ll f;
            read(f);
            if(f==1)
            {
                ll l,r,k;
                read(l);
                read(r);
                read(k);
                update(l,r,1,n,1,k);
            }
            else
            {
                ll l,r;
                read(l);
                read(r);
                write(query(l,r,1,n,1));
                putchar('
    ');
            }
        }
        return 0;
    }
  • 相关阅读:
    块数据加密模式
    "jobTracker is not yet running"(hadoop 配置)
    平衡搜索树
    Programming Assignment 3: Collinear Points
    Programming Assignment 2: Randomized Queues and Deques
    Programming Assignment 1: Percolation
    1007. Maximum Subsequence Sum (25)
    Link List
    1081. Rational Sum (20)
    strassen algorithm
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/10792819.html
Copyright © 2011-2022 走看看