zoukankan      html  css  js  c++  java
  • 算法模板 线段树

    区间修改 查询等 详见注释

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<string>
    #include<stack>
    #include<map>
    using namespace std;
    const int INF=0x3f3f3f3f;
    typedef pair<int, int> P;
    typedef long long ll;
    #define fi first/
    #define se scond
    #define me(x) memset(x, -1, sizeof(x))
    #define mem(x) memset(x, 0, sizeof(x))
    #define sc(x) scanf("%lld", &x)
    #define sca(x,y) scanf("%lld%lld", &x, &y)
    #define pr(x) printf("%lld
    ", x)
    #define pri(x) printf("%lld ", x)
    #define fo(i,n) for(i=0; i<n; i++)
    #define rfo(i,n) for(i=n-1; i>=0; i--)
    #define N 2000000 + 5
    
    ll tree[N*4];
    ll lazy[N*4];
    void push_up(ll rt)
    {
        tree[rt]=tree[rt<<1] + tree[rt<<1|1];
    }
    //向下传lazy标记
    void push_down(ll rt, ll len)
    {
        lazy[rt<<1] += lazy[rt]; //左右子树标记更新
        lazy[rt<<1|1] += lazy[rt];
        //左右子树数值更新
        tree[rt<<1] += (len-(len>>1)) * lazy[rt];//奇数长度 左子树更长
        tree[rt<<1|1] += (len>>1) * lazy[rt];
    
        lazy[rt]=0;//取消该节点标记
    }
    /*
    //建树
               1
         2           3
       4    5      6     7
      8 9        12 13
    e.g.  n=6 data:1 2 3 4 5 6
          tree[8]=1
          tree[9]=2
          tree[5]=3
          tree[12]=4
          tree[13]=5
          tree[7]=6
    */
    void build(ll rt, ll l, ll r)
    {
        if(l==r)
        {
            cin>>tree[rt];
            return ;
        }
        ll m=r+l >> 1;
        build(rt<<1, l, m);
        build(rt<<1|1, m+1, r);
        push_up(rt); //向上更新父节点
    }
    //单点更新
    /*
    void update(ll rt, ll l, ll r, ll p, ll x, ll k)
    {
        if(l==r)
        {
            if(k==1)
            tree[rt]+=x;
            else tree[rt]-=x;
            return ;
        }
        ll m = l+r >>1;
        if(p<=m) update(rt<<1, l, m, p, x, k);
        else update(rt<<1|1, m+1, r, p, x, k);
        push_up(rt);
    }
    */
    //区间更新
    void Update(ll rt, ll l, ll r, ll p, ll L, ll R)
    {
        if(L<=l && r<=R) //缩到指定区间 更新
        {
            tree[rt]+=(r-l+1)*p;
            lazy[rt]+=p; //更新标记
            return ;
        }
        if(lazy[rt]) push_down(rt, r-l+1); //及时下传标记
        ll m= r+l >> 1;
        if(L<=m) Update(rt<<1, l, m, p, L, R);
        if(R>m) Update(rt<<1|1, m+1, r, p, L, R);
        push_up(rt);
    }
    //区间查询
    ll query(ll rt, ll l, ll r, ll L, ll R)
    {
        if(L<=l && r<=R)
        {
            return tree[rt];
        }
        ll s=0;
        if(lazy[rt]) push_down(rt,r-l+1); //及时下传标记
        ll m = r+l >>1;
        if(L<=m) s+=query(rt<<1, l, m, L, R);
        if(R>m) s+=query(rt<<1|1, m+1, r, L, R);
        return s;
    }
    int main()
    {
        ll i, j , k;
        ll n, m;
        ll L, R, p;
        cin>>n>>m;
    
        build(1,1,n);
    
        //for(i=1; i<=20; i++) cout<<i<<' '<<tree[i]<<endl;
    
        fo(i,m)
        {
            char c;
            cin>>c;
            if(c=='Q')
            {
                cin>>L>>R;
                if(L>R) swap(L,R);
                k=query(1,1,n,L,R);
                cout<<k<<endl;
            }
            else if(c=='C')
            {
                cin>>L>>R;
                if(L>R) swap(L,R);
                cin>>p;
                Update(1,1,n,p,L,R);
            }
        }
    }
  • 相关阅读:
    flutter 中 List 和 Map 的用法
    AndroidStudio中Flutter打包APK
    flutter中的异步机制 Future
    [控件] 画饼状图的控件
    用CAShapeLayer写股市K线图动画效果
    使用Instruments中的CoreAnimation分析动画
    山寨Facebook的Shimmer效果
    maskView遮罩中多张图片的动画
    将CAGradientLayer用作maskView的遮罩图层
    [翻译] JKLLockScreenViewController
  • 原文地址:https://www.cnblogs.com/op-z/p/10763417.html
Copyright © 2011-2022 走看看