【线段树成段更新成段查询模板】【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\n",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\n",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;
}



你可能感兴趣的:(【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst)