poj3468A Simple Problem with Integers

题目大意:

区间更新,区间查找。

解题思路:

注意数据范围,然后线段树lazy标记就行了,很基础,没什么技巧。

#include<stdio.h>
#define N 100005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define node rt,l,r
__int64  value[N];
struct Node{
    __int64  k;
    __int64  v;
};
Node tree[N*4];
void up(int rt)
{
    tree[rt].v=tree[rt<<1].v+tree[rt<<1|1].v;
}
void build(int rt,int l,int r)
{
    tree[rt].k=0;
    if(l==r)
    {
        tree[rt].v=value[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    up(rt);
}
void down(int rt,int l,int r)
{
    long long k=tree[rt].k;//这个地方没有用64错了好多次。。。
    if(k!=0)
    {
        tree[rt<<1].k+=k;tree[rt<<1|1].k+=k;///不能可能前面待更新的不止一个
        int mid=(l+r)>>1;
        tree[rt<<1].v+=(mid-l+1)*k;
        tree[rt<<1|1].v+=(r-mid)*k;
        tree[rt].k=0;
    }
}
__int64 Query(int rt, int l, int r, int a, int b)
{
    if(a<=l&&r<=b)
    {
        return tree[rt].v;
    }
    down(node);
    int mid=(l+r)>>1;
    if(b<=mid)
        return Query(lson,a,b);
    else if(a>mid)
         return Query(rson,a,b);
    else
    {
        return Query(lson,a,b)+Query(rson,a,b);
    }
   up(rt);
}
void add(int rt,int l,int r,int a,int b,__int64  c)
{
    if(l>=a&&r<=b)
    {
        tree[rt].k+=c;
        tree[rt].v+=(r-l+1)*c;
        return ;
    }
    down(node);
    int mid=(l+r)>>1;
    if(b<=mid)
        add(lson,a,b,c);
    else if(a>mid)
        add(rson,a,b,c);
    else{
        add(lson,a,b,c);
        add(rson,a,b,c);
    }
    up(rt);
}
int main()
{
    int n,m,i,a,b;
    __int64 c,ans;
    char op[10];
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%I64d",&value[i]);
    build(1,1,n);
    while(m--){
        scanf("%s",&op);
        if(op[0]=='Q'){
                scanf("%d%d",&a,&b);
                ans=Query(1,1,n,a,b);
                printf("%I64d\n",ans);
        }else{
            scanf("%d%d%I64d",&a,&b,&c);
            add(1,1,n,a,b,c);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值