POJ 3468 A Simple Problem with Integers(線段樹)

這題剛開始用的普通的累加方法,果斷超時...中間做些小改變就行了,還有就是結果要用long long 



題目鏈接 點擊打開鏈接


代碼註釋:


<strong><span style="font-size:18px;color:#ff6600;">#include<iostream>
#include<cstdio>
#define N 100000
using namespace std;
int s[N+5];
struct node
{
    int l,r;
    long long sum,n; //數比較大用 long long
} a[N*3];
void build(int l,int r,int i)
{
    a[i].l=l;
    a[i].r=r;
    a[i].n=0;
    if(l==r)
    {
        a[i].sum=s[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,2*i);
    build(mid+1,r,2*i+1);
    a[i].sum=a[2*i].sum+a[2*i+1].sum;//向上更新
}
void insert(int l,int r,int c,int i)
{
    if(a[i].l==l&&a[i].r==r)
    {
        a[i].n+=c;
        return;
    }
    a[i].sum+=(long long)c*(r-l+1); //更新時把每段的總和算出來
    int mid=(a[i].l+a[i].r)/2;
    if(r<=mid)
        insert(l,r,c,2*i);
    else if(l>mid)
        insert(l,r,c,2*i+1);
    else
    {
        insert(l,mid,c,2*i);
        insert(mid+1,r,c,2*i+1);
    }
}
long long cal(int l,int r,int i)
{
    if(a[i].l==l&&a[i].r==r)
        return a[i].sum+(long long)(r-l+1)*a[i].n;
    if(a[i].n!=0)  // 本題關鍵就在這,相當於把權值向下傳遞
    {
        a[2*i].n+=a[i].n;
        a[2*i+1].n+=a[i].n;
        a[i].sum+=(long long)(a[i].r-a[i].l+1)*a[i].n;//同上算出每段的sum,最後加起來方便
        a[i].n=0;
    }
    int mid=(a[i].l+a[i].r)/2;
    if(r<=mid)
        return cal(l,r,2*i);
    else if(l>mid)
        return cal(l,r,2*i+1);
    else
        return cal(l,mid,2*i)+cal(mid+1,r,2*i+1);
}
int main()
{
    int n,m,x,y,i,c;
    while(scanf("%d%d",&n,&m)!=EOF)//用cin可能超時
    {
        for(i=1; i<=n; i++)
            scanf("%d",&s[i]);
        build(1,n,1);
        char o;
        while(m--)
        {
            getchar(); //這裏不要忘了...
            scanf("%c",&o);
            if(o=='Q')
            {
                scanf("%d%d",&x,&y);
                printf("%lld\n",cal(x,y,1));
            }
            else
            {
                scanf("%d%d%d",&x,&y,&c);
                insert(x,y,c,1);
            }
        }

    }
}
</span></strong>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章