poj 3468A Simple Problem with Integers(树状数组区间修改)

来源:互联网 发布:淘宝哪家多肉土好 编辑:程序博客网 时间:2024/05/18 02:54

题目链接:http://poj.org/problem?id=3468

思路:s[i]表示原来1到i的和 s1[i]表示区间修改后1到i的和    区间修改为[l,r]区间上加a

i<ls1[i]=s[i]l<=i<=rs1[i]=s[i]+a*i-a*(l-1)r<is1[i]=s[i]+a*(r-l+1)

sum[i]=c[i]*i+d[i]

则与上图表格对应的修改为

c在l处+a

c在r+1处-a

d在l处-a*(l-1)

d在r+1处+a*r

#include<cstdio>#include<cstring>using namespace std;const int num=100005;__int64 c[num],d[num];int n,m;int lowbit(int a){    return a&(-a);}void add(__int64 *a,int p,int ad){    while(p<=n)    {        a[p]+=ad;        p+=lowbit(p);    }}__int64 sum(__int64 *a,int p){    __int64 s=0;    while(p>0)    {        s+=a[p];        p-=lowbit(p);    }    return s;}int main(){    int i,a,b,q;    __int64 ans;    char s[3];    //freopen("in.txt","r",stdin);    scanf("%d%d",&n,&m);    memset(c,0,sizeof(c));    memset(d,0,sizeof(d));    for(i=1;i<=n;i++)    {        scanf("%d",&a);        add(d,i,a);    }    while(m--)    {        scanf("%s",s);        if(s[0]=='Q')        {            scanf("%d%d",&a,&b);            ans=(b*sum(c,b)+sum(d,b))-((a-1)*sum(c,a-1)+sum(d,a-1));  //注意此处求[a,b]为sum[b]-sum[a-1]            printf("%I64d\n",ans);        }        else        {            scanf("%d%d%d",&a,&b,&q);            add(c,a,q);            add(c,b+1,-q);            add(d,a,-q*(a-1));            add(d,b+1,q*b);        }    }    return 0;}



0 0
原创粉丝点击