http://acm.whu.edu.cn/land/problem/detail?problem_id=1464

题目:

There are n numbers with the corresponding NO.1-n, and the value of the i-th number is xi. 

 
Define three operations:
 
    1.Division a b c, in the interval [a,b], if the value of a number is equal or greater than zero, then its value changed to it divide C(integer division). (1 <= a <= b <= n, 1 <= c <= 50000)
 
    2.Minus a b c, all numbers in the interval [a, b] subtract c. (1 <= a <= b <= n ,1<= c <= 50000) 
 
    3.Sum a b, query for the sum of all numbers in the interval [a, b]. (1 <= a <= b <= n)
思路:
线段树,对减法,直接用常规方法,除法暴力算,用flag标记下区间,下次可能就不这个区间就不用算了;
代码:
View Code
#include <cstdio>
#define N 100005
typedef long long LL;
struct st
{
    LL x,y,flag,sum,add;
}p[N * 5];
LL a[N];
void build(LL r,LL x,LL y)
{
    p[r].x = x;
    p[r].y = y;
    p[r].add = 0;
    if(x == y)
    {
        p[r].sum = a[x];
        if(a[x] > 0)
        p[r].flag = 1;
        else
        p[r].flag = 0;
        return ;
    }
    LL mid = (x + y) >> 1,tem = r * 2;
    build(tem,x,mid);
    build(tem + 1,mid + 1,y);
    p[r].sum = p[tem].sum + p[tem + 1].sum;
    if(p[tem].flag || p[tem + 1].flag)
    p[r].flag = 1;
    else
    p[r].flag = 0;
}
void dd(LL r,LL x,LL y,LL d)
{
    if(!p[r].flag)
    return ;
    if(p[r].x == x && p[r].y == y && x == y)
    {
        if(p[r].sum > 0)
        {
            p[r].sum = p[r].sum / d;
            if(p[r].sum > 0)
            p[r].flag = 1;
            else
            p[r].flag = 0;
        }
        else
        p[r].flag = 0;
        return ;
    }
    LL mid = (p[r].x + p[r].y) >> 1,tem = r * 2;
    if(p[r].add)
    {
        p[tem].sum += (p[tem].y - p[tem].x + 1) * p[r].add;
        p[tem].add += p[r].add;
        p[tem + 1].sum += (p[tem + 1].y - p[tem + 1].x + 1) * p[r].add;
        p[tem + 1].add += p[r].add;
        p[r].add = 0;
    }
    if(y <= mid)
    dd(tem,x,y,d);
    else if(x > mid)
    dd(tem + 1,x,y,d);
    else
    {
        dd(tem,x,mid,d);
        dd(tem + 1,mid + 1,y,d);
    }
    if(p[tem].flag || p[tem + 1].flag)
    p[r].flag = 1;
    else
    p[r].flag = 0;
   p[r].sum = p[tem].sum + p[tem + 1].sum;

}
void insert(LL r,LL x,LL y,LL add)
{
    if(p[r].x == x && p[r].y == y)
    {
        p[r].sum += (y - x + 1) * add;
        p[r].add += add;
        return ;
    }
    LL mid = (p[r].x + p[r].y) >> 1,tem = r * 2;
    if(p[r].add)
    {
        p[tem].sum += (p[tem].y - p[tem].x + 1) * p[r].add;
        p[tem].add += p[r].add;
        p[tem + 1].sum += (p[tem + 1].y - p[tem + 1].x + 1) * p[r].add;
        p[tem + 1].add += p[r].add;
        p[r].add = 0;
    }
    if(y <= mid)
    insert(tem,x,y,add);
    else if(x > mid)
    insert(tem + 1,x,y,add);
    else
    {
        insert(tem,x,mid,add);
        insert(tem + 1,mid + 1,y,add);
    }
    p[r].sum = p[tem].sum + p[tem + 1].sum;
}
LL query(LL r,LL x,LL y)
{
    LL sum = 0;
    if(p[r].x == x && p[r].y == y)
    {
        return p[r].sum;
    }
     LL mid = (p[r].x + p[r].y) >> 1,tem = r * 2;
    if(p[r].add)
    {
        p[tem].sum += (p[tem].y - p[tem].x + 1) * p[r].add;
        p[tem].add += p[r].add;
        p[tem + 1].sum += (p[tem + 1].y - p[tem + 1].x + 1) * p[r].add;
        p[tem + 1].add += p[r].add;
        p[r].add = 0;
    }
     if(y <= mid)
     sum += query(tem,x,y);
     else if(x > mid)
     sum += query(tem + 1,x,y);
     else
     sum = sum + query(tem,x,mid) + query(tem + 1,mid + 1,y);
     return sum;
}
int main()
{
    LL t,u = 0;
    scanf("%lld",&t);
    while(t --)
    {
        LL n,m;
        scanf("%lld %lld",&n,&m);
        for(LL i = 1;i <= n;i ++)
        scanf("%lld",&a[i]);
        build(1,1,n);
        char ch[10];
        LL x,y,z;
        printf("Case %lld:\n",++ u);
        while(m --)
        {
            scanf("%s",ch);
            if(ch[0] == 'D')
            {
                scanf("%lld %lld %lld",&x,&y,&z);
                if(z > 1)
                dd(1,x,y,z);
            }
            else if(ch[0] == 'M')
            {
                scanf("%lld %lld %lld",&x,&y,&z);
                insert(1,x,y,-z);
            }
            else
            {
                scanf("%lld %lld",&x,&y);
                printf("%lld\n",query(1,x,y));
            }
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2013-04-17 11:27  fly_lovelove  阅读(242)  评论(0编辑  收藏  举报