uva 12501 - Bulky process of bulk reduction

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3945

题意:给一个序列,有两种操作:

1、query i j : a[i]*1+a[i+1]*2+a[i+2]*3+....+a[j]*(j+1)的值。

2、change i j u:把区间[i,j]的值都加上u。

思路:用线段树维护两个值s1,s2:

s1为当前区间[l,r]的a[l]*1+a[l+1]*2+a[l+2]*3+....+a[r]*(r+1)的值。

s2为当前区间[l,r]的a[l]+a[l+1]+a[l+2]+....a[r]的和。

这样如果包含有某个区间。那就这样区间的值就是s1+s2*c,c为这个区间前有多少个数。

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#define MD long long md = (l + r) >> 1
using namespace std;
const long long maxn = 100005;

struct nd{
    long long tp,sum,s;
}as[maxn*4];
long long n,m;
inline void pushUp(long long rt,long long c)
{
    as[rt].s = as[rt<<1].s + as[rt<<1|1].s;
    as[rt].sum = as[rt<<1].sum + as[rt<<1|1].s * c + as[rt<<1|1].sum;
}
inline void pushDown(long long rt,long long l,long long m,long long r){
    as[rt<<1].tp += as[rt].tp;
    as[rt<<1|1].tp += as[rt].tp;
    as[rt<<1].s += (m - l + 1) * as[rt].tp;
    as[rt<<1|1].s += (r - m) * as[rt].tp;
    as[rt<<1].sum += (m - l + 2) * (m - l + 1) / 2 * as[rt].tp;
    as[rt<<1|1].sum += (r - m + 1) * (r - m) / 2 * as[rt].tp;
    as[rt].tp = 0;
}
void build(long long rt,long long l,long long r){
    MD;
    as[rt].tp = 0;
    if(l==r){
        as[rt].sum = 100;
        as[rt].s = 100;
        return ;
    }
    build(rt<<1,l,md);
    build(rt<<1|1,md+1,r);
    pushUp(rt,md-l+1);
}
void update(long long rt,long long l,long long r,long long L,long long R,long

long v)
{
    MD;
    if(L<=l && r<=R){
        as[rt].tp += v;
        as[rt].sum += (r - l + 2) * (r - l + 1) / 2 * v;
        as[rt].s += (r - l + 1) * v;
        return ;
    }
    if(as[rt].tp)pushDown(rt,l,md,r);
    if(L<=md)update(rt<<1,l,md,L,R,v);
    if(R>md)update(rt<<1|1,md+1,r,L,R,v);
    pushUp(rt,md-l+1);
}
long long ans;
void query(long long rt,long long l,long long r,long long L,long long R)
{
    MD;
    if(L<=l && r<=R){
        ans += as[rt].s * (l - L) + as[rt].sum;
        return ;
    }
    if(as[rt].tp)pushDown(rt,l,md,r);
    if(L<=md)query(rt<<1,l,md,L,R);
    if(R>md)query(rt<<1|1,md+1,r,L,R);
    pushUp(rt,md-l+1);
}
int main()
{
    long long t,cas=0;
    scanf("%lld",&t);
    while(t--){
        scanf("%lld %lld",&n,&m);
        build(1,1,n);
        char s[10];
        long long l,r,v;
        printf("Case %lld:\n",++cas);
        while(m--){
            scanf("%s",s);
            if(s[0]=='q'){
                ans=0;
                scanf("%lld %lld",&l,&r);
                query(1,1,n,l,r);
                printf("%lld\n",ans);
            }else{
                scanf("%lld %lld %lld",&l,&r,&v);
                update(1,1,n,l,r,v);
            }
        }
    }
    return 0;
}

posted on 2012-10-07 12:13  aigoruan  阅读(263)  评论(0)    收藏  举报

导航