P4513 Beginners Wander Park Line Trees

Keywords: C++

Topic Background

Xiao Xin often accompanies Xiao Bai to play in the park, which is the so-called dog walk.

Topic Description

There is a "Park Road" near Xiaoxinjia. On one side of the road, there are nn parks in turn from south to north. Xiaobai has looked at them for a long time, and he does not know which parks to visit.

From the beginning, Xiao Bai scored each park according to its scenery -. -. In order to save time, Xiao Xin sets a range for each dog walk. Xiao Bai can only choose between the aath and bbth parks (including aa and bb parks) and choose consecutive parks to play in. Xiao Bai of course hopes that the total score of the selected park will be as high as possible. At the same time, because the landscape of some parks will change, Xiaobai's score may also change.

Then, please come and help Xiaobai choose the park.

Input format

The first line, two integers, NN and M M, denote the number of parks and the total number of operations (walking dogs or changing scores), respectively.
Next, NN lines, an integer for each line, give the park's score at the beginning of Xiaobai in turn.
Next MM lines, three integers per line. The first integer KK, 11 or 22.

  • K=1K=1 means Xiaoxin is going to take Xiaobai out to play. The next two integers a A and B B give the scope of choosing the park (1 < a,b < N1 < a,b < N). The test data may be a > Ba > b and need to be exchanged.
  • K=2K=2 indicates that Xiaobai changed the score of a park, and the next two integers P P and ss indicate that Xiaobai changed the score of the pp park to ss (1 < p < N1 < p < n).
    Among them, 1 < N < 500 0001 < N < 500000, 1 < M < 100 0001 < M < 100000, all scores are integers whose absolute value does not exceed 10001000000.

Output format

Every time Xiao Bai goes out to play, he outputs a line corresponding to the output, which contains only one integer, indicating the maximum score and sum of the park that Xiao Bai can choose.

Input and Output Samples

Input #1 replication
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3
Output #1 replication
2
-1


Finding the Longest Continuous Sum of Intervals


Sometimes it's much more convenient to use structured segment trees for interval merging.
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node
{
    int l,r,lc,rc,lm,rm,ans,tot;
}node[4000005];
int n,m,k,x,y,cnt=0,a[500001];
void maintain(int x)//Maintain updates and merge answers
{
    int ll=node[x].lc,rr=node[x].rc;
    node[x].tot=node[ll].tot+node[rr].tot;
    node[x].lm=max(node[ll].lm,node[ll].tot+node[rr].lm);
    node[x].rm=max(node[rr].rm,node[rr].tot+node[ll].rm);
    node[x].ans=max(max(node[ll].ans,node[rr].ans),node[ll].rm+node[rr].lm);
}
void build(int l,int r,int now)
{
    node[now].l=l;
    node[now].r=r;
    if(l==r)
    {
        node[now].lm=node[now].rm=node[now].tot=node[now].ans=a[l];//Initial Value Assignment
        return;//Don't forget it return
    }
    int mid=(l+r)>>1;
    node[now].lc=2*now;
    build(l,mid,node[now].lc);
    node[now].rc=2*now+1;
    build(mid+1,r,node[now].rc);
    maintain(now);//Combine answers
}
void update(int now,int to,int num)
{
    int x=node[now].l,y=node[now].r;
    if(x==y)
    {
        node[now].lm=node[now].rm=node[now].tot=node[now].ans=num;//modify
        return;
    }
    int mid=(x+y)>>1;
    if(to<=mid) update(node[now].lc,to,num);
    else update(node[now].rc,to,num);
    maintain(now);//Combine answers
}
Node query(int now,int l,int r)
{
    int x=node[now].l,y=node[now].r;
    if(l<=x&&r>=y) return node[now];//The current node returns the answer directly in the query interval.
    int mid=(x+y)>>1,ll=node[now].lc,rr=node[now].rc;
    if(r<=mid) return query(ll,l,r);
    else if(l>mid) return query(rr,l,r);
    else//Interrogation Interval Crossing mid Combine the answers, ideas and answers. maintain It's almost the same in the function, so I won't go into any more details here.
    {
        Node t,t1=query(ll,l,r),t2=query(rr,l,r);
        t.tot=t1.tot+t2.tot;
        t.lm=max(t1.lm,t1.tot+t2.lm);
        t.rm=max(t2.rm,t2.tot+t1.rm);
        t.ans=max(max(t1.ans,t2.ans),t1.rm+t2.lm);
        return t;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&k,&x,&y);
        if(k==1) 
        {
            if(x>y) swap(x,y);
            printf("%d\n",query(1,x,y).ans);
        }
        else update(1,x,y);
    }
    return 0;
}

Posted by pagie on Sat, 27 Jul 2019 22:58:10 -0700