线段树 || BZOJ1756: Vijos1083 小白逛公园 || P4513 小白逛公园

题面:小白逛公园

题解:

对于线段树的每个节点除了普通线段树该维护的东西以外,额外维护lsum(与左端点相连的最大连续区间和)、rsum(同理)和sum……就行了

代码:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define max(a,b) ((a)>(b)?(a):(b))
 5 using namespace std;
 6 inline int rd(){
 7     int x=0,f=1;char c=getchar();
 8     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
 9     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
10     return f*x;
11 }
12 const int maxn=500000+50,maxm=100000+50,inf=1<<30;
13 int N,M,K,P,S,ans,flag;
14 struct Tree{int lsum,rsum,l,r,mx,sum;}t[maxn<<2],now;
15 inline void Pushup(int x){
16     int ls=x<<1,rs=ls|1;
17     t[x].sum=t[ls].sum+t[rs].sum;
18     t[x].lsum=max(t[ls].lsum,t[ls].sum+t[rs].lsum);
19     t[x].rsum=max(t[rs].rsum,t[rs].sum+t[ls].rsum);
20     t[x].mx=max(t[ls].mx,t[rs].mx);
21     t[x].mx=max(t[x].mx,t[ls].rsum+t[rs].lsum);
22     return;
23 }
24 inline void Build(int x,int l,int r){
25     t[x].l=l;t[x].r=r;int mid=(l+r)>>1;
26     if(l==r){
27         t[x].sum=t[x].lsum=t[x].rsum=t[x].mx=rd();
28         return;
29     }
30     Build(x<<1,l,mid);Build(x<<1|1,mid+1,r);
31     Pushup(x);
32     return;
33 }
34 inline void Update(int x,int p,int s){
35     int l=t[x].l,r=t[x].r,mid=(l+r)>>1,ls=x<<1,rs=ls|1;
36     if(l==r&&l==p){
37         t[x].sum=t[x].lsum=t[x].rsum=t[x].mx=s;
38         return;
39     }
40     if(p<=mid)Update(ls,p,s);else Update(rs,p,s);
41     Pushup(x);
42     return;
43 }
44 inline void Query(int x,int ql,int qr){
45     int l=t[x].l,r=t[x].r,mid=(l+r)>>1,ls=x<<1,rs=ls|1;
46     if(ql<=l&&r<=qr){
47         if(flag==-1){
48             flag=0;
49             now.lsum=t[x].lsum;now.rsum=t[x].rsum;
50             now.mx=t[x].mx;now.sum=t[x].sum;
51         }
52         else{
53             int sum,lsum,rsum,mx;
54             sum=now.sum+t[x].sum;
55             lsum=max(now.lsum,now.sum+t[x].lsum);
56             rsum=max(t[x].rsum,now.rsum+t[x].sum);
57             mx=max(now.mx,t[x].mx);
58             mx=max(mx,now.rsum+t[x].lsum);
59             now.sum=sum;now.lsum=lsum;now.rsum=rsum;now.mx=mx;
60         }
61         return;
62     }
63     if(ql<=mid)Query(ls,ql,qr);if(qr>mid)Query(rs,ql,qr);
64     return;
65 }
66 int main(){
67     N=rd();M=rd();
68     Build(1,1,N);
69     while(M--){
70         K=rd();P=rd();S=rd();
71         if(K==1){
72             if(P>S)swap(P,S);
73             flag=-1;
74             Query(1,P,S);
75             ans=now.mx;
76             printf("%d\n",ans);
77         }
78         else Update(1,P,S);
79     }
80     return 0;
81 }

 


By:AlenaNuna

 

转载于:https://www.cnblogs.com/AlenaNuna/p/10440300.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值