zoukankan      html  css  js  c++  java
  • 【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst

    题目大意:

    2个操作

    A.区间a b 增加 c

    B 查询a b;


    注意事项:1.记住要清除标记

                    2.查询时要下放标记,但没必要向上更新


    线段:自带的,不用建模

    区间和性质:sum;

    /*
    WA 1次 以为不要LONG LONG
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    const int maxn=100000+5;
    using namespace std;
    int N,Q;
    LL tree[maxn*4];
    LL col[maxn*4];
    void PushUp(int rt)
    {
        tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    }
    int build(int l,int r,int rt)
    {
        col[rt]=0;
        if(l==r){scanf("%lld",&tree[rt]);return 0;}
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void Pushdown(int rt,int k)          //k是长度
    {
        if(col[rt])
            {
                col[rt<<1]+=col[rt];
                col[rt<<1|1]+=col[rt];
                tree[rt<<1]+=(k-(k>>1))*col[rt];
                tree[rt<<1|1]+=(k>>1)*col[rt];
                col[rt]=0;
            }
    }
    int update(int L,int R,int c,int l,int r,int rt) {
           if (L<=l&&r<= R) {
                  col[rt]+=c;               //不同题目处理方式不同 ,
                  tree[rt]+=(LL)c*(r-l+1);
                  return 0;
           }
           Pushdown(rt,r-l+1);             //Lazy 下放
           int m=(l+r)>>1;                  //下面与以往一样
           if (L<=m) update(L,R,c,lson);
           if (R>m) update(L,R,c,rson);
           PushUp(rt);
    }
    LL query(int L,int R,int l,int r,int rt)
    {
        LL temp=0;
        if(L<=l&&r<=R){return tree[rt];}
        Pushdown(rt,r-l+1);
        int m=(l+r)>>1;
        if(L<=m) temp+=query(L,R,lson);
        if(R>m)  temp+=query(L,R,rson);
        return temp;
    }
    void solve()
    {
        char temp;
        int a,b,c;
        getchar();
        for(int i=1;i<=Q;i++)
        {
            scanf("%c",&temp);
            if(temp=='Q')
            {
                scanf("%d%d",&a,&b);
                printf("%lld
    ",query(a,b,1,N,1));
            }
            else if(temp=='C')
            {
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1,N,1);
            }
            getchar();
        }
    }
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    int main()
    {
      //  init();
        while(cin>>N>>Q)
        {
            build(1,N,1);
            solve();
        }
        return 0;
    }
    

    全long long 形式

    /*
    WA 1次 以为不要LONG LONG
    WA 2次 全LONG LONG为妙
    WA 3次 m 忘记改成long long 了
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    const int maxn=100000+5;
    using namespace std;
    int N,Q;
    LL tree[maxn*4];
    LL col[maxn*4];
    void PushUp(int rt)
    {
        tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    }
    int build(LL l,LL r,int rt)
    {
        col[rt]=0;
        if(l==r){scanf("%lld",&tree[rt]);return 0;}
        LL m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void Pushdown(int rt,LL k)          //k是长度
    {
        if(col[rt])
            {
                col[rt<<1]+=col[rt];
                col[rt<<1|1]+=col[rt];
                tree[rt<<1]+=(k-(k>>1))*col[rt];
                tree[rt<<1|1]+=(k>>1)*col[rt];
                col[rt]=0;
            }
    }
    int update(int L,int R,LL c,LL l,LL r,int rt) {
           if (L<=l&&r<= R) {
                  col[rt]+=c;               //不同题目处理方式不同 ,
                  tree[rt]+=c*(r-l+1);
                  return 0;
           }
           Pushdown(rt,r-l+1);             //Lazy 下放
           LL m=(l+r)>>1;                  //下面与以往一样
           if (L<=m) update(L,R,c,lson);
           if (R>m) update(L,R,c,rson);
           PushUp(rt);
    }
    LL query(int L,int R,LL l,LL r,int rt)
    {
        LL temp=0;
        if(L<=l&&r<=R){return tree[rt];}
        Pushdown(rt,r-l+1);
        LL m=(l+r)>>1;
        if(L<=m) temp+=query(L,R,lson);
        if(R>m)  temp+=query(L,R,rson);
        return temp;
    }
    void solve()
    {
        char temp;
        LL a,b;
        LL c;
        getchar();
        for(int i=1;i<=Q;i++)
        {
            scanf("%c",&temp);
            if(temp=='Q')
            {
                scanf("%lld%lld",&a,&b);
                printf("%d
    ",query(a,b,1,N,1));
            }
            else if(temp=='C')
            {
                scanf("%lld%lld%lld",&a,&b,&c);
                update(a,b,c,1,N,1);
            }
            getchar();
        }
    }
    void init()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    }
    int main()
    {
      //  init();
        while(cin>>N>>Q)
        {
            build(1,N,1);
            solve();
        }
        return 0;
    }
    



  • 相关阅读:
    IntelliJ IDEA错误: 源值1.5已过时,将在未来所有版本中删除
    AcWing 311. 月之谜 数位dp
    AcWing 306. 杰拉尔德和巨型象棋 计数类DP
    AcWing 296. 清理班次2 线段树优化dp
    luogu P3052 [USACO12MAR]Cows in a Skyscraper G
    luogu P5664 Emiya 家今天的饭 容斥+dp
    AcWing 289. 环路运输 滑动窗口单调队列优化
    AcWing 288. 休息时间 滚动数组+分类讨论
    AcWing 287. 积蓄程度 树形dp,换根
    luogu P3842 [TJOI2007]线段 线性dp
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480379.html
Copyright © 2011-2022 走看看