羅区[P1438]列ボーリング

ツリーライン等差数列を追加します(ライト)

意味:
二つのタイプに分けアレイ、M操作:
1は、間隔の[L、R]の演算の順序で添加した
変化のR点列のクエリ結果の後、2
:思考
追加:ツリーで演算シーケンスは、セグメントツリーに加え、いくつかの連続した演算のシーケンスに分割されます。
クエリ:すべての値のクエリ点場合間隔、加算和+ =(R -ツリー[ステップ] .L)* D + K。

#include <cstdio>
using namespace std;
const int MAXN = 1e5+5;
struct node{
    int l,r;
    int a,d;
}tree[MAXN<<2];
int num[MAXN];
void Build(int l,int r,int step){
    tree[step].l=l;
    tree[step].r=r;
    tree[step].a=0;
    tree[step].d=0;
    if(l==r){
        return;
    }
    int mid=(l+r)>>1;
    Build(l,mid,step<<1);
    Build(mid+1,r,step<<1|1);
}
void Add(int l,int r,int a,int d,int step){
    if(tree[step].l>r||tree[step].r<l)return;
    if(tree[step].l>=l&&tree[step].r<=r){
        tree[step].a+=(a+(tree[step].l-l)*d);
        tree[step].d+=d;
        return;
    }
    Add(l,r,a,d,step<<1|1);
    Add(l,r,a,d,step<<1);
}
int sum;
void Query(int q,int step){
    if(tree[step].l>q||tree[step].r<q)return;
    sum+=(q-tree[step].l)*tree[step].d+tree[step].a;
    Query(q,step<<1);
    Query(q,step<<1|1);
}
int main(){
    int N,M;
    scanf("%d%d",&N,&M);
    Build(1,N,1);
    for(int i=0;i<N;i++){
        scanf("%d",&num[i]);
    }
    while(M--){
        int opr;
        scanf("%d",&opr);
        if(opr==1){
            int l,r,a,d;
            scanf("%d%d%d%d",&l,&r,&a,&d);
            Add(l,r,a,d,1);
        }
        else{
            int r;
            scanf("%d",&r);
            sum=0;
            Query(r,1);
            printf("%d\n",sum+num[r-1]);
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/Vagrant-ac/p/12003250.html