1. 程式人生 > >Codeforces Round #179 (Div. 1) A題 線段樹

Codeforces Round #179 (Div. 1) A題 線段樹

有m個操作,每個操作給出l,r,d值,表示從a(l)到a(r)區間內的每個值加d。

接下來k個範圍,每個範圍為x到y,表示從第x個操作到第y個操作都執行一次。

輸出最後得到的陣列a。

兩次線段樹,第一次求出每種操作各需要多少次,第二次根據第一次結果求出最終結果。

程式碼如下

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 200000000
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define maxm 200005
__int64 time[maxm<<2],lazy1[maxm<<2],cover[maxm<<2],lazy2[maxm<<2],a[maxm+5],op[maxm+5][3];
void pushdown1(__int64 rt)
{
    time[rt]+=lazy1[rt];
    lazy1[rt<<1]+=lazy1[rt];
    lazy1[rt<<1|1]+=lazy1[rt];
    lazy1[rt]=0;
}
void build1(__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    time[rt]=0;
    lazy1[rt]=0;
    if(r>l)
    {
        mid=(l+r)>>1;
        build1(lson);
        build1(rson);
    }
}
void update1(__int64 L,__int64 R,__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    if(L<=l&&r<=R)
    {
        lazy1[rt]++;
        return ;
    }
    pushdown1(rt);
    if(r>l)
    {
        mid=(l+r)>>1;
        if(L<=mid) update1(L,R,lson);
        if(R>mid) update1(L,R,rson);
    }
}
__int64 search1(__int64 d,__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    pushdown1(rt);
    if(l==r)
    {
        return time[rt];
    }
    mid=(l+r)>>1;
    if(d<=mid)
        return search1(d,lson);
    else
        return search1(d,rson);
}

void build2(__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    cover[rt]=0;
    lazy2[rt]=0;
    if(r>l)
    {
        mid=(l+r)>>1;
        build2(lson);
        build2(rson);
    }
}
void pushdown2(__int64 rt)
{
    cover[rt]+=lazy2[rt];
    lazy2[rt<<1]+=lazy2[rt];
    lazy2[rt<<1|1]+=lazy2[rt];
    lazy2[rt]=0;
}
void update2(__int64 L,__int64 R,__int64 c,__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    if(L<=l&&r<=R)
    {
        lazy2[rt]+=c;
        return ;
    }
    pushdown2(rt);
    if(r>l)
    {
        mid=(l+r)>>1;
        if(L<=mid)update2(L,R,c,lson);
        if(R>mid)update2(L,R,c,rson);
    }
}
__int64 search2(__int64 d,__int64 l,__int64 r,__int64 rt)
{
    __int64 mid;
    pushdown2(rt);
    if(l==r)
        return cover[rt];
    mid=(l+r)>>1;
    if(d<=mid)
        return search2(d,lson);
    else
        return search2(d,rson);
}
int main()
{
    __int64 i,j,k,l,n,m,kk,le,ri;
    while(scanf("%I64d%I64d%I64d",&n,&m,&kk)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
        for(i=1;i<=m;i++)
            scanf("%I64d%I64d%I64d",&op[i][0],&op[i][1],&op[i][2]);
        build1(1,m,1);
        for(i=1;i<=kk;i++)
        {
            scanf("%I64d%I64d",&le,&ri);
            update1(le,ri,1,m,1);
        }
        build2(1,n,1);
        for(i=1;i<=m;i++)
        {
            j=op[i][2];
            k=search1(i,1,m,1);
            update2(op[i][0],op[i][1],j*k,1,n,1);
        }
        for(i=1;i<n;i++)
            printf("%I64d ",a[i]+search2(i,1,n,1));
        printf("%I64d\n",a[i]+search2(i,1,n,1));
    }
    return 0;
}