poj A Simple Problem with Integers

这道题,做了好几次,彻头彻尾的经典线段树。

#include<stdio.h>
#define HH 1
struct st
{
    __int64 l;
    __int64 r;
    __int64 color;
    __int64 num;
    __int64 sum;
}f[100001*4];
__int64 date[100002];
void build(__int64 l,__int64 r,__int64 n)
{
    __int64 mid=(l+r)/2;
    f[n].l=l;
    f[n].r=r;
    f[n].color=0;
    f[n].num=0;
    if(l==r)
    {
        f[n].sum=date[l];
        return ;
    }
    build(l,mid,n*2);
    build(mid+1,r,n*2+1);
    f[n].sum=f[n*2].sum+f[n*2+1].sum;
}
void down(__int64 n)
{
    f[n].color=0;
    if(f[n*2].color==HH)
        f[n*2].num+=f[n].num;
    else
        f[n*2].num=f[n].num;
    if(f[n*2+1].color==HH)
        f[n*2+1].num+=f[n].num;
    else 
        f[n*2+1].num=f[n].num;
    f[n*2].color=HH;
    f[n*2+1].color=HH;
    f[n*2].sum+=(f[n*2].r-f[n].l+1)*f[n].num;
    f[n*2+1].sum+=(f[n*2+1].r-f[n*2+1].l+1)*f[n].num;
    f[n].num=0;
}
void up(__int64 n)
{
    f[n].sum=f[n*2].sum+f[n*2+1].sum;
}
void update(__int64 l,__int64 r,__int64 num,__int64 n)
{
    __int64 mid=(f[n].l+f[n].r)/2;
    if(f[n].l==l&&f[n].r==r)
    {
        if(f[n].color==HH)
            f[n].num+=num;
        else
            f[n].num=num;
        f[n].color=HH;
        f[n].sum=f[n].sum+(f[n].r-f[n].l+1)*num;
        return ;
    }
    if(f[n].color==HH)
        down(n);
    if(mid>=r)
        update(l,r,num,n*2);
    else if(mid<l)
        update(l,r,num,n*2+1);
    else{
        update(l,mid,num,n*2);
        update(mid+1,r,num,n*2+1);
    }
    up(n);

}
__int64 query(__int64 l,__int64 r,__int64 n)
{
    __int64 mid=(f[n].l+f[n].r)/2,cos=0;
    if(f[n].l==l&&f[n].r==r)
    {
    //    printf("%d %d %d %d..\n",f[n].l,f[n].r,f[n].num,f[n].sum);
        return f[n].sum;
    }
    if(f[n].color==HH)
        down(n);
    if(mid>=r)
       cos+=query(l,r,n*2);
    else if(mid<l)
       cos+=query(l,r,n*2+1);
    else
    {
        cos+=query(l,mid,n*2);
        cos+=query(mid+1,r,n*2+1);
    }
    return cos;
}
int main()
{
    __int64 i,j,n,t,q,l,r,num;
    __int64 k;
    char c[10];
    while(scanf("%I64d%I64d",&n,&q)>0)
    {
        for(i=1;i<=n;i++)
            scanf("%I64d",&date[i]);
        build(1,n,1);
        getchar();
        while(q--)
        {
            scanf("%s",c);
            if(c[0]=='Q')
            {
                scanf("%I64d%I64d",&l,&r);
                k=query(l,r,1);
                printf("%I64d\n",k);
            }
            else if(c[0]=='C')
            {
                scanf("%I64d%I64d%I64d",&l,&r,&num);
                update(l,r,num,1);
            }
        }
    }
    return 0;
}

过的时间还是比较多,要改进才行。

posted @ 2013-04-23 19:19  芷水  阅读(162)  评论(0编辑  收藏  举报