【vijos】P1083 小白逛公园

【算法】线段树

【题解】

学自:https://vijos.org/p/1083/solution(wang_yanheng的回答)

回溯时维护一段区间的以下域:

  • sumL:从左端点起连续区间的最大和
  • sumR:从右端点起连续区间的最大和
  • sum:整段区间的和
  • subSum:最大子区间和

以上域在叶子节点中的值,都等于节点代表公园的评分
设当前节点为 x,左孩子为 l,右孩子为 r。则:

x.sumL = MAX(l.sumL, l.sum + r.sumL);
x.sumR = MAX(r.sumR, r.sum + l.sumR);
x.sum = l.sum + r.sum;
x.subSum = MAX(l.subSum, r.subSum, l.sumR + r.sumL);
以上计算过程可以写成函数,参数结构体,返回结构体。
查询时要返回结构体。
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f,maxn=500010;
struct cyc{int lsum,rsum,sum,subsum;}t[maxn*3];
int a[maxn],L[maxn*3],R[maxn*3],n,m;
cyc calc(cyc a,cyc b)
{
    cyc c;
    c.lsum=max(a.lsum,a.sum+b.lsum);
    c.rsum=max(b.rsum,b.sum+a.rsum);
    c.sum=a.sum+b.sum;
    c.subsum=max(a.subsum,max(b.subsum,a.rsum+b.lsum));
    return c;
}
void build(int k,int l,int r)
{
    L[k]=l;R[k]=r;
    if(l==r)t[k]={a[l],a[l],a[l],a[l]};
     else
      {
         int mid=(l+r)>>1;
         build(k<<1,l,mid);
         build(k<<1|1,mid+1,r);
         t[k]=calc(t[k<<1],t[k<<1|1]);
      } 
}
void update(int k,int x,int num)
{
    int left=L[k],right=R[k];
    if(left==right)t[k]={num,num,num,num};
     else
      {
         int mid=(left+right)>>1;
         if(x<=mid)update(k<<1,x,num);
          else update(k<<1|1,x,num);
         t[k]=calc(t[k<<1],t[k<<1|1]);
      }
}
cyc ask(int k,int l,int r)
{
    int left=L[k],right=R[k];
    if(l<=left&&right<=r)return t[k];
     else
      {
          int mid=(left+right)>>1;
          if(l>mid)return ask(k<<1|1,l,r);
          if(r<=mid)return ask(k<<1,l,r);
          return calc(ask(k<<1,l,r),ask(k<<1|1,l,r));
      }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++)
     {
         int k,b,c;
         scanf("%d%d%d",&k,&b,&c);
         if(k==1)
          {
              if(b>c)swap(b,c);
            printf("%d
",ask(1,b,c).subsum);
         }
        else update(1,b,c);
     }
}
View Code
 
原文地址:https://www.cnblogs.com/onioncyc/p/5795052.html