0.题面:

给出正整数n和一个(1 <= n <= 100 000)长度的数列,要求找出一个子区间,使这个子区间的数字和乘上子区间中的最小值最大。输出这个最大值与区间的两个端点。

1.思路

一开始试图使用单调栈,然而在调试一上午无果后愤然打了个分治,然后就过了233

根据分治三步法,算法流程分为:

1.分解:定义 \(dfs(l,r)\) 为区间 \([l,r]\) 的最优解,\(mid = (l+r)/2\) ,可以把问题分为 \(dfs(l,mid)\) 和 \(dfs(mid+1,r)\) 两部分,分别对应最优解完全位于左子区间和右子区间的情况。

2.边界:当 \(l=r\) 时,\(dfs(l,r)={a_l}^2\)。(数列为\(a\))

3.合并:在第一步处理了最优解完全位于左子区间和右子区间的情况,还有最优解跨越 \(mid\) 的情况没处理。注意到当最小值一定时,区间越大越好,所以可以从大到小地选择最大值,再从中点开始往左右两端“放宽”当前区间。

2.Code

#include <bits/stdc++.h>
using namespace std;
#define MAXN 1000000
typedef long long ll;
int n;
ll a[MAXN+5],sum[MAXN+5],ans;
struct answ{
int l,r;ll v;
answ(){
l=r=v=0;
}
answ(int L,int R,ll V){
l=L;r=R;v=V;
}
};
bool operator < (answ l,answ r){
return l.v<r.v;
}
struct ST{
ll st[MAXN+1][31];
int query(int l,int r){
int k=log2(r-l+1);
return min(st[l][k],st[r-(1<<k)+1][k]);
}
void build(){
for(int i=1;i<=n;i++){
st[i][0]=a[i];
}
for(int j=1;j<=30;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
}qwq;
ll query(int l,int r){
return qwq.query(l,r)*(sum[r]-sum[l-1]);
}//求一个区间的“数字和乘上子区间中的最小值”
answ dfs(int l,int r){//分治主体
int mid=(l+r)/2;
if(l==r){//边界
return answ(l,r,query(l,r));
}
answ ans=max(dfs(l,mid),dfs(mid+1,r));
vector<int> tmp;
for(int i=l;i<=r;i++){
tmp.push_back(a[i]);
}
sort(tmp.begin(),tmp.end());reverse(tmp.begin(),tmp.end());//从大到小地取区间最小值
int L=mid,R=mid+1;
ans=max(ans,answ(L,R,query(L,R)));
for(int i=0;i<tmp.size();i++){//由于最小值“逐渐放宽”,所以区间只增不减
if(tmp[i]>a[mid]||tmp[i]>a[mid]){
continue;
}
while(a[L-1]>=tmp[i]&&L!=l){
L--;
}
while(a[R+1]>=tmp[i]&&R!=r){
R++;
}//区间越大越好
ans=max(ans,answ(L,R,query(L,R)));
}
return ans;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
qwq.build();
answ ans=dfs(1,n);
cout<<ans.v<<endl;
cout<<ans.l<<" "<<ans.r<<endl;
return 0;
}

最新文章

  1. Ubuntu16.04配置phpmyadmin
  2. UE4 Windows平台部署游戏到IOS 第一部分
  3. Asp.Net Web API 2第一课——入门
  4. R(四): R开发实例-map分布图
  5. ubuntu 14.04 安装git server
  6. [原创]使用benchmarksql和pgbench对PostgreSQL Plus Advanced Server进行性能测试
  7. Java Math的floor,round,ceil函数小结
  8. C#第十二天
  9. 学习MVC之租房网站(九)-房源显示和搜索
  10. webservice03#schema#元素属性定义
  11. APPScan安装与使用教程
  12. Axios发送AJAX请求
  13. CSS3制作上下跳动动画箭头效果
  14. pt站 扫盲贴 面向小白
  15. cookie和session的区别和用法
  16. 2017-2018-2 20155314《网络对抗技术》Exp1 PC平台逆向破解(5)M
  17. 【CLR】详解CLR中的程序集
  18. AI的胜利,人类的荣耀
  19. excel的小bug
  20. 动态创建控件 #Create(...)

热门文章

  1. 【LeetCode】1128. Number of Equivalent Domino Pairs 等价多米诺骨牌对的数量(Python)
  2. 【LeetCode】230. 二叉搜索树中第K小的元素 Kth Smallest Element in a BST
  3. 【LeetCode】609. Find Duplicate File in System 解题报告(Python & C++)
  4. Java EE数据持久化框架笔记 • 【目录】
  5. Java高级程序设计笔记 • 【第3章 多线程(二)】
  6. Java链式调用
  7. Ranger知识地图
  8. Kerberos加密级别不支持的问题
  9. Spring 处理请求和响应相关的注解
  10. PL/SQL连接时,报无法解析指定的字符串