poj3735区间查询

树状数组

#include<cstdio>
using namespace std;

const int NUM=100005;
long long n,m,a[NUM],c1[NUM],c2[NUM];

long long GetLL()
{    long long ret=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
    return ret*f;
}
long long lowbit(long long x){return x&(-x);}
void Add(long long x,long long k)
{    long long i;
    for(i=x;i<=n;i+=lowbit(i)){c1[i]+=k;c2[i]+=x*k;}
}
long long Sum(long long x)
{    long long Ans1=0,Ans2=0,i;
    for(i=x;i>0;i-=lowbit(i)){Ans1+=c1[i];Ans2+=c2[i];}
    return Ans1*(x+1)-Ans2;
}
int main(){
    long long i,x,y;char ch;a[0]=0;
    n=GetLL();m=GetLL();
    for(i=1;i<=n;i++){a[i]=GetLL();a[i]+=a[i-1];}
    while(m--)
    { while(ch=getchar())if(ch=='Q'||ch=='C')break;
      x=GetLL();y=GetLL();
      if(ch=='C'){i=GetLL();Add(x,i);Add(y+1,-i);}
      else printf("%lld\n",a[y]-a[x-1]+Sum(y)-Sum(x-1));
    }
    return 0;
}
View Code

线段树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define maxn 200020
using namespace std;
struct node{
    int l,r;
    long long sum;
}tree[maxn*4];
int a[maxn],tag[maxn*4],n,l,r,d,q;
char ch;
void build(int l,int r,int s){
    tree[s].l=l; tree[s].r=r;
    if (l==r){tree[s].sum=a[l]; return;}
    int m=(l+r)>>1;
    build(l,m,s<<1);
    build(m+1,r,s<<1|1);
    tree[s].sum=tree[s<<1].sum+tree[s<<1|1].sum;
}
void pushdown(int s,int m){
    tag[s<<1]+=tag[s];
    tag[s<<1|1]+=tag[s];
    tree[s<<1].sum+=tag[s]*(m-(m>>1));
    tree[s<<1|1].sum+=tag[s]*(m>>1);
    tag[s]=0;
}
void add(int l,int r,int s){
    if (l<=tree[s].l && tree[s].r<=r) {tag[s]+=d;tree[s].sum+=d*(tree[s].r-tree[s].l+1);return;}
    if (tag[s]) pushdown(s,tree[s].r-tree[s].l+1);
    int m=(tree[s].l+tree[s].r)>>1;
    if (l<=m) add(l,r,s<<1);
    if (r>m) add(l,r,s<<1|1);
    tree[s].sum=tree[s<<1].sum+tree[s<<1|1].sum;
}
long long ask(int l,int r,int s){
    if (l<=tree[s].l && tree[s].r<=r) return tree[s].sum;
    if (tag[s]) pushdown(s,tree[s].r-tree[s].l+1);
    int m=(tree[s].l+tree[s].r)>>1;
    long long tmp=0;
    if (l<=m) tmp+=ask(l,r,s<<1);
    if (m<r) tmp+=ask(l,r,s<<1|1);
    return tmp;
}
int main(){
    scanf("%d%d",&n,&q);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    build(1,n,1);
    for (int i=1;i<=q;i++){
        ch=getchar();
        while (ch!='Q' && ch!='C') ch=getchar();
        if (ch=='Q'){
            scanf("%d%d",&l,&r);
            printf("%lld\n",ask(l,r,1));
        }
        else {
            scanf("%d%d%d",&l,&r,&d);
            add(l,r,1);
        }
    }
}
View Code

 

posted @ 2015-11-12 23:30  fqqq  阅读(74)  评论(0)    收藏  举报