POJ3468:A Simple Problem with Integers——题解

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

 

实现一个线段树,能够做到区间修改和区间查询和。

明显板子题。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
inline ll read(){
    ll X=0,w=0; char ch=0;
    while(ch<'0' || ch>'9') {w|=ch=='-';ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
ll tree[400001],b[100001];
ll lazy[400001];
void build(int a,int l,int r){
    lazy[a]=0;
    if(l==r){
    tree[a]=b[l];
    return;
    }
    int mid=(l+r)/2;
    build(a*2,l,mid);
    build(a*2+1,mid+1,r);
    tree[a]=tree[a*2]+tree[a*2+1];
    return;
}
inline void push(int a,int l,int mid,int r){
    lazy[a*2+1]+=lazy[a];
    lazy[a*2]+=lazy[a];
    tree[a*2+1]+=lazy[a]*(r-mid);
    tree[a*2]+=lazy[a]*(mid-l+1);
    lazy[a]=0;
    return;
}
ll wen(int a,int l,int r,int l1,int r1){
    if(l1<=l&&r1>=r){
    return tree[a];
    }
    if (l1>r||r1<l) return 0;
    int mid=(l+r)/2;
    push(a,l,mid,r);
    return wen(a*2,l,mid,l1,r1)+wen(a*2+1,mid+1,r,l1,r1);
}
void gai(int a,int l,int r,int l1,int r1,int add){
    if (l1>r||r1<l) return;
    if(l1<=l&&r1>=r){
    lazy[a]+=add;
    tree[a]+=add*(r-l+1);
    return;
    }
    int mid=(l+r)/2;
    push(a,l,mid,r);
    gai(a*2,l,mid,l1,r1,add);
    gai(a*2+1,mid+1,r,l1,r1,add);
    tree[a]=tree[a*2]+tree[a*2+1];
    return;
}
int main(){
    int m=read();
    int ha=read();
    for(int i=1;i<=m;i++){
    b[i]=read();
    }
    build(1,1,m);
    for(int i=1;i<=ha;i++){
    char w;
    cin>>w;
    if(w=='C'){
        int a1=read();
        int a2=read();
        int a3=read();
        gai(1,1,m,a1,a2,a3);
    }else{
        int x=read();
        int y=read();
        printf("%lld\n",wen(1,1,m,x,y));
    }
    }
    return 0;
}

 

posted @ 2017-11-20 15:37  luyouqi233  阅读(237)  评论(0编辑  收藏  举报