poj Asimple Problem With Integers

http://poj.org/problem?id=3468

题目大意:

给你n个整数,两种操作,

求一段区间的和 

一段区间内全部加上某个整数

简单线段树题

区间内一部分是固定区间和

另一个是此区间内每个数都需要加的量

注意用64为整数

详情见代码注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<algorithm>

using namespace std;

const int N=100005;

struct node

{

    int l,r;

    long long add;//非固定,需要向下传递的量

    long long v;//固定住的和

}mem[N*4];

int a[N];

long long ans;

void build(int x,int l,int r)

{

    mem[x].l=l;

    mem[x].r=r;

    mem[x].add=0;//初始化

    if(l==r)

    {

        mem[x].v=a[l];

    }

    else

    {

        int mid=(l+r)>>1;

        build(x*2,l,mid);

        build(x*2+1,mid+1,r);

        mem[x].v=mem[x*2].v+mem[x*2+1].v;

    }

}

void findsum(int x,int i,int j)

{

    if(mem[x].l==i&&mem[x].r==j)

    {

        ans=ans+mem[x].v+(mem[x].r-mem[x].l+1)*mem[x].add;//如果正好是这个区间

    }

    else

    {

        int mid=(mem[x].l+mem[x].r)>>1;

        mem[x].v+=(mem[x].r-mem[x].l+1)*mem[x].add;//否则向下传递,首先本区间固定量增加

        mem[x*2].add+=mem[x].add;mem[x*2+1].add+=mem[x].add;//然后传给左右区间

        mem[x].add=0;//最后清零

        if(j<=mid)

        {

            findsum(x*2,i,j);

        }else if(i>mid)

        {

            findsum(x*2+1,i,j);

        }else

        {

            findsum(x*2,i,mid);

            findsum(x*2+1,mid+1,j);

        }

    }

}

void Addint(int x,int i,int j,int k)

{

    if(mem[x].l==i&&mem[x].r==j)

    {

        mem[x].add+=k;//本区间改变增加量

    }

    else

    {

        mem[x].v+=(j-i+1)*k;//向下的话,首先本区间先将固定量增加

        int mid=(mem[x].l+mem[x].r)>>1;

        if(j<=mid)

        {

            Addint(x*2,i,j,k);

        }else if(i>mid)

        {

            Addint(x*2+1,i,j,k);

        }else

        {

            Addint(x*2,i,mid,k);

            Addint(x*2+1,mid+1,j,k);

        }

    }

}

int main()

{

    int n,m;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        for(int i=1;i<=n;++i)

        {

            scanf("%d",&a[i]);

        }

        build(1,1,n);

        while(m--)

        {

            char c;

            int i,j,k;

            getchar();//吃换行

            scanf("%c",&c);

            if(c=='Q')

            {

                scanf("%d %d",&i,&j);

                ans=0;

                findsum(1,i,j);

                printf("%I64d\n",ans);

            }

            else

            {

                scanf("%d %d %d",&i,&j,&k);

                Addint(1,i,j,k);

            }

        }

    }

    return 0;

}

  

你可能感兴趣的:(Integer)