White P4513 the park (request interval maximum segment tree and sub-segment)

 Topic links: https://www.luogu.org/problem/P4513

Topic background

Often accompany new small white to the park, also known as walking the dog friends ...

Title Description

There is a small home near the "Park Road" side of the road from south to north row of the n- the n-parks, white long look tired, I had no idea what to go the park to play.

At first, white will give each park hit points -.- according to landscape the park. To save the new small, dog each time will advance a predetermined range, white you can only select the first A A-th and b between b parks (including A A, b b park two) of consecutive selected Park play. White certainly hope that the sum of the park scores slightly selected as high as possible. Also, because some of the park's landscape will change, so the white scoring there may be some changes.

So, please come help you choose white park it.

Input Format

The first line, two integers N N and M M, respectively, showing operation of the park and the number (or changing scoring dog) total.
Next N N lines, each integer, in turn gives white scored at the start of the park.
Next M M rows, each row of three integers. First integer K K, . 1 . 1 or 2 2

  • . 1 = K K = . 1 represents, small white to take out a new play, the next two integers A A and B B are given range (selecting park 1 ≦ a, b≤N . 1 A , B N ). Test data may occur A> b A > where b is required to be exchanged;
  • 2 = K K = 2, he said white changed scored a park, the next two integers p p and S S, white represents the first p scoring parks became p S S ( 1 ≦ p≤N . 1 P N).
    Wherein, 1≤N≤500 000 . 1 N . 5 0 0 0 0 0, 1≤M≤100 000 . 1 M . 1 0 0 0 0 0, the absolute value of all the scores are not more than 1000 . 1 0 0 0 integer.

Output Format

White out to play every time, corresponds to the output line, just an integer representing the maximum value and the white points can be selected park.

Sample input and output

Input # 1
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 2 3
Output # 1
2 
-1 
thinking:
This is a board problem tree line, the use of tree line maintenance intervals and the largest sub-segment
of solving the problem is to maintain a dynamic meaning of the questions with the largest sub-segment and modify.
We found that the largest sub-segment and can be updated by some maintenance intervals to a merger of the two sections, so you can maintain a tree line.
Specifically how to maintain?
We let the tot [i] i represents the sum of the number of nodes representative of range,
LM [i] i represents the node represents the range from the left endpoint (must include the left point) and the largest sub-segment,
RM [i] denote the i Representative interval starts from the right end node (must include a right end point) and the maximum sub-segment,
ANS [i] i represents the largest sub-segment interval and the node represents. So that we can answer the merger of the two intervals. Update and maintain specific code is as follows.
void Push_up ( int RT) 
{ 
    int LL = Node [RT] .lc, RR = Node [RT] .rc; 
    Node [RT] .tot = Node [LL] + .tot Node [RR] .tot; // Update sum
     // update the start point of the left and the largest sub-segment. Both cases are not crossing across the mid and mid 
    Node [RT] = max .lm (Node [LL] .lm, Node [LL] + .tot Node [RR] .lm);
     // Update the right starting point and the largest sub-segment. Both cases are not crossing across the mid and mid 
    Node [RT] .rm = max (Node [RR] .rm, Node [RR] + .tot Node [LL] .rm);
     // updates the maximum sub-segment, and s answer. Three cases: the largest sub-segment only in the left mid, across the mid, only the right MID 
    Node [RT] .ans = max (max (Node [LL] .ans, Node [RR] .ans), Node [LL ] + .rm Node [RR] .lm); 
}

See the complete code:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=5e5+5;
struct Node
{
    int l,r,lc,rc,lm,rm,ans,tot;
}node[maxn<<2];
int n,m,k,x,y,cnt=0,a[maxn];
void Push_up(int rt)
{
    int ll=node[rt].lc,rr=node[rt].rc;
    node[rt].tot=node[ll].tot+node[rr].tot;//更新总和
    // update the start point of the left and the largest sub-segment. Both cases are not crossing across the mid and mid 
    Node [RT] = max .lm (Node [LL] .lm, Node [LL] + .tot Node [RR] .lm);
     // Update the right starting point and the largest sub-segment. Both cases are not crossing across the mid and mid 
    Node [RT] .rm = max (Node [RR] .rm, Node [RR] + .tot Node [LL] .rm);
     // updates the maximum sub-segment, and s answer. Three cases: the largest sub-segment only in the left mid, across the mid, only the right MID 
    Node [RT] .ans = max (max (Node [LL] .ans, Node [RR] .ans), Node [LL ] + .rm Node [RR] .lm); 
} 
void the Build ( int L, int R & lt, int RT) 
{ 
    Node [RT] .L = L; 
    Node [RT] .r = R & lt;
     IF (L == R & lt) 
    { 
        Node [RT] .lm=node[rt].rm=node[rt].tot=node[rt].ans=a[l];
        return ;
    }
    int mid=(l+r)>>1;
    node[rt].lc=rt<<1;
    Build(l,mid,node[rt].lc);
    node[rt].rc=rt<<1|1;
    Build(mid+1,r,node[rt].rc);
    Push_up(rt);//合并答案
}
Node Query(int rt,int l,int r)
{
    int x=node[rt].l,y=node[rt].r;
    if(l<=x&&y<=r) returnNode [RT]; // current node returns the answer to the interrogation interval which directly 
    int MID = (X + Y) >> . 1 , Node LL = [RT] .lc, RR = Node [RT] .rc;
     IF (R & lt < mid =) // all sections of the left 
        return Query (LL, L, R & lt);
     the else  IF (L> mid) // all right section 
        return Query (RR, L, R & lt);
     the else  // query across the mid section to merge the idea at the answer almost Pushup function 
    { 
        the Node T, T1 = Query (LL, L, R & lt), T2 = Query (RR, L, R & lt); 
        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;
    }
}
void Update(int rt,int to,int num)
{
    int x=node[rt].l,y=node[rt].r;
    if(x==y)
    {
        node[rt].lm=node[rt].rm=node[rt].tot=node[rt].ans=num;//修改
        return ;
    }
    int mid=(x+y)>>1;
    if(to<=mid) Update(node[rt].lc,to,num);
    else Update(node[rt].rc,to,num);
    Push_up(rt);
}
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;
}

 

Guess you like

Origin www.cnblogs.com/caijiaming/p/11440112.html