JDOJ 1842 Magictree

JDOJ 1842 Magictree

题目传送门

Description

Fox住在魔法岛上,他种了一排N棵魔法树(标号0..N-1,高度Ai),接下来的M天,每天Del都会来(Del是Fox的朋友),或者问Fox一些问题,或者帮助Fox对这些树施魔法.于是有两种形式:

1.询问第a棵树到第b棵树的总高度
2.对第a棵树到第b棵树施魔法,使它们长高c单位

Input

第一行,两个整数N,M

第二行,N个整数,表示fox种的魔法树的初始高度

接下来M行,有两种情况

1.Q a b 表示询问a到b的高度和

2.C a b c 表示对a到b施魔法c

Output

M行,对于每一个询问给出一个答案。

Sample Input

10 5 1 2 3 4 5 6 7 8 9 10 Q 3 3 Q 0 9 Q 1 3 C 2 5 3 Q 1 3

Sample Output

4 55 9 15

HINT

80%的数据保证 N<=100,M<=100

100%的数据保证 N<=2000000,M<=2000,0<=Ai<=100,0<=c<=250000000


题解:

线段树板子题。

不会请走这边

简单线段树

以及其他的线段树大礼包:

权值线段树

动态开点线段树

可持久化线段树(主席树)

附上代码:

#include<cstdio>
#include<algorithm>
#define lson pos<<1
#define rson pos<<1|1
#define ll long long
using namespace std;
const int maxn=2*1e6+10;
int n,m,tot;
ll a[maxn],ans[maxn];
ll tree[maxn<<2];
ll lazy[maxn<<2];
void build1(int pos,int l,int r)
{
    int mid=(l+r)>>1;
    if(l==r)
    {
        tree[pos]=a[l];
        return;
    }
    build1(lson,l,mid);
    build1(rson,mid+1,r);
    tree[pos]=tree[lson]+tree[rson];
}
void pushup(int pos)
{
    tree[pos]=tree[lson]+tree[rson];
}
void mark(int pos,int l,int r,ll k)
{
    lazy[pos]+=k;
    tree[pos]+=(r-l+1)*k;
}
void pushdown(int pos,int l,int r)
{
    int mid=(l+r)>>1;
    mark(lson,l,mid,lazy[pos]);
    mark(rson,mid+1,r,lazy[pos]);
    lazy[pos]=0;
}
void update(int pos,int l,int r,int x,int y,ll k)
{
    int mid=(l+r)>>1;
    if(x<=l && r<=y)
    {
        mark(pos,l,r,k);
        return;
    }
    pushdown(pos,l,r);
    if(x<=mid)
        update(lson,l,mid,x,y,k);
    if(y>mid)
        update(rson,mid+1,r,x,y,k);
    pushup(pos);
}
ll query(int pos,int l,int r,int x,int y)
{
    int mid=(l+r)>>1;
    ll ret=0;
    if(x<=l && r<=y)
        return tree[pos];
    pushdown(pos,l,r);
    if(x<=mid)
        ret+=query(lson,l,mid,x,y);
    if(y>mid)
        ret+=query(rson,mid+1,r,x,y);
    return ret;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    build1(1,1,n);
    while(m--)
    {
        ll x,y,k;
        char opt[2];
        scanf("%s",opt);
        if(opt[0]=='Q')
        {
            scanf("%lld%lld",&x,&y);
            ans[++tot]=query(1,1,n,x+1,y+1);
        }
        else if(opt[0]=='C')
        {
            scanf("%lld%lld%lld",&x,&y,&k);
            update(1,1,n,x+1,y+1,k);
        }
    }
    for(int i=1;i<=tot;i++)
        printf("%lld
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/13681028.html