题目链接:http://codevs.cn/problem/3981/

题解:

线段树求GSS模板题

一、一段长的区间的 GSS 有三种情况:
>1 完全在左子区间
>2 完全在右子区间
>3 横跨左右区间

二、需维护的信息:

mx 区间GSS  ——用来更新情况1、2

lmx 区间最大前缀——用来更新情况3

rmx 区间最大后缀——用来更新情况3

sum 区间和——lmx,rmx

三、建树

1、初始化:区间需维护的信息最初都赋为输入值

2、合并区间信息

mx:3种情况中的最大值

lmx:左区间的lmx, 左区间的sum+右区间lmx  取大

rmx 同理

四、查询

情况1、2很简单

情况3的合并与上面的合并区间信息同理

#include<cstdio>
#include<algorithm>
#include<iostream> using namespace std; #define N 200000
#define inf -1e18
typedef long long LL; int n,m;
int L,R; struct node
{
LL lmx,rmx,mx,sum;
void clear()
{
lmx=rmx=sum=mx=inf;
} }tree[N*+]; template <typename T>
void read(T &x) //读入优化
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
} void out(LL ans) //输出优化
{
if(ans<) { putchar('-'); ans=-ans; }
char s[]; int len=;
do s[++len]=ans%+''; while(ans/=);
while(len) putchar(s[len--]); putchar('\n');
} void up(int k) //线段树上区间信息合并
{
int l=k<<,r=k<<|;
tree[k].mx=max(tree[l].mx,tree[r].mx);
tree[k].mx=max(tree[k].mx,tree[l].rmx+tree[r].lmx);
tree[k].lmx=max(tree[l].lmx,tree[l].sum+tree[r].lmx);
tree[k].rmx=max(tree[r].rmx,tree[r].sum+tree[l].rmx);
tree[k].sum=tree[l].sum+tree[r].sum;
} void build(int k,int l,int r) //建树
{
if(l==r)
{
read(tree[k].mx);
tree[k].lmx=tree[k].rmx=tree[k].sum=tree[k].mx;
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
up(k);
} node query(int k,int l,int r) // 查询
{
if(l>=L&&r<=R) return tree[k];
int mid=l+r>>;
if(R<=mid) return query(k<<,l,mid); //查询区间完全在左子区间
if(L>mid) return query(k<<|,mid+,r); //查询区间完全在右子区间
//查询区间跨左右区间
node lans; lans.clear();
lans=query(k<<,l,mid);
node rans; rans.clear();
rans=query(k<<|,mid+,r);
node ans;
ans.clear();
ans.mx=max(lans.mx,rans.mx); //GSS完全在左或右区间
ans.mx=max(lans.rmx+rans.lmx,ans.mx); //GSS跨左右区间
ans.lmx=max(lans.lmx,lans.sum+rans.lmx);
ans.rmx=max(rans.rmx,rans.sum+lans.rmx);
ans.sum=lans.sum+rans.sum;
return ans;
} void init()
{
read(n);
build(,,n);
read(m);
LL ans;
for(int i=;i<=m;++i)
{
read(L); read(R);
ans=query(,,n).mx;
out(ans);
}
} int main()
{
init();
return ;
}

最新文章

  1. Module Zero之Nuget包
  2. WebService 用法
  3. eclipse- Web-app verson=2.5 调整将Dynamic Web Module3.0降为2.5
  4. asp.net 微信支付 错误解决方案
  5. UiAutomator环境搭建及详细操作
  6. [推荐] kylinPET是一款功能强大的性能测试工具
  7. Spring IoC反转控制的快速入门
  8. C#_控件——DropDownList
  9. [转]linux系统磁盘分区之parted
  10. UVa 10256 - The Great Divide 判断凸包相交
  11. 九度OJ 1361 翻转单词顺序
  12. ORACLE功能GREATEST功能说明具体实例
  13. Object -C self -- 笔记
  14. HDU 3376 &amp;amp;&amp;amp; 2686 方格取数 最大和 费用流裸题
  15. 源码分析Android Handler是如何实现线程间通信的
  16. Angular2快速起步——构建一个简单的应用
  17. Gitlab_ansible_jenkins三剑客④jenkins安装图解及freestyle的简单使用
  18. 今日报错Cannot access java.lang.String
  19. HBase篇--HBase常用优化
  20. python把文件从一个目录复制到另外一个目录,并且备份

热门文章

  1. python 做词云图
  2. 【IntelliJ IDEA】idea部署服务到Tomcat的工作原理
  3. PyTorch中MaxPool的ceil_mode属性
  4. &#39;while&#39; statement cannot complete without throwing an exception
  5. IC卡、ID卡、M1卡、射频卡的区别是什么(射频卡是种通信技术)
  6. Android Studio出现Wait for build to finish解决办法
  7. 学习笔记之知识图谱 (Knowledge Graph)
  8. Android 解决Execution failed for task &#39;:app:clean.&#39;报错
  9. (原)Ubuntu连接远程服务器时connection reset by peer
  10. dos2unix的使用