【Foreign】划分序列 [线段树][DP]
划分序列
Time Limit: 20 Sec Memory Limit: 256 MB
Description

Input

Output
仅一行一个整数表示答案。
Sample Input
9 4
1 1 1 3 2 2 1 3 1
Sample Output
5
HINT

Main idea
将序列分为若干段,使得和最大的那一段最小,值可以为负。
Source
首先,显然都想到了二分答案。
我们先把都为正数或负数的情况写了:Ai>=0的时候求出最小的划分段数x,若x<=K则表示当前答案可行;Ai<=0的时候求出最大的划分段数x,若x>=K则表示当前答案可行。然后再打了暴力,接着我们对拍一下,惊讶地发现了一个规律:若最小划分段数为L,最大划分段数为R,当L<=K<=R时则可以更新。
然后我们用DP来求L和R,也就是:若一段的和满足<=mid,则可以分为一段。
然后我们发现,可以用线段树优化寻找1~i-1中的最小值或最大值,这样判断就可以满足效率了。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std;
typedef long long s64; const int INF = ;
const int ONE = 5e4+; int n,block;
int L,R;
int x,sum[ONE],s[ONE];
int li[ONE],li_num;
int f_min[ONE],f_max[ONE];
int res_min,res_max;
int Zero; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} namespace Seg
{
struct power
{
int minn;
int maxx;
}Node[ONE]; void Build(int i,int l,int r)
{
Node[i].minn = INF;
Node[i].maxx = -INF;
if(l==r) return;
int mid=(l+r)>>;
Build(i<<,l,mid); Build(i<<|,mid+,r);
} void Update(int i,int l,int r,int L,int x,int PD)
{
if(l==r)
{
if(!PD) Node[i].minn = x;
else Node[i].maxx = x;
return;
}
int mid=(l+r)>>;
if(L<=mid) Update(i<<,l,mid,L,x,PD);
else Update(i<<|,mid+,r,L,x,PD);
Node[i].minn = min(Node[i<<].minn, Node[i<<|].minn);
Node[i].maxx = max(Node[i<<].maxx, Node[i<<|].maxx);
} void Query(int i,int l,int r,int L,int R)
{
if(L<=l && r<=R)
{
res_min=min(res_min, Node[i].minn);
res_max=max(res_max, Node[i].maxx);
return;
}
int mid=(l+r)>>;
if(L<=mid) Query(i<<,l,mid,L,R);
if(mid+<=R) Query(i<<|,mid+,r,L,R);
}
} int Check(int mid)
{
Seg::Build(,,li_num);
Seg::Update(,,li_num, Zero,,);
Seg::Update(,,li_num, Zero,,);
for(int i=;i<=n;i++)
{
int pos = lower_bound(li+,li+li_num+,sum[i] - mid) - li;
res_min = INF; res_max = -INF; Seg::Query(,,li_num, ,pos);
f_min[i] = res_min + ;
f_max[i] = res_max + ;
Seg::Update(,,li_num, s[i],f_min[i],);
Seg::Update(,,li_num, s[i],f_max[i],);
}
return (f_min[n]<=block && block<=f_max[n]);
} int main()
{
n=get(); block=get();
li[++li_num] = ;
for(int i=;i<=n;i++)
{
x=get();
li[++li_num] = sum[i] = sum[i-] + x;
if(x < ) L+=x; else R+=x;
} sort(li+,li+li_num+);
li_num = unique(li+,li+li_num+) - li - ; for(int i=;i<=n;i++)
s[i]=lower_bound(li+,li+li_num+, sum[i]) - li;
Zero = lower_bound(li+,li+li_num+, ) - li; while(L < R - )
{
int mid=(L+R)>>;
if(Check(mid)) R = mid;
else L = mid;
} if(Check(L)) printf("%d",L);
else printf("%d",R);
}
【Foreign】划分序列 [线段树][DP]的更多相关文章
- hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)
小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- 【Foreign】阅读 [线段树][DP]
阅读 Time Limit: 10 Sec Memory Limit: 256 MB Description Input Output Sample Input 0 10 4 10 2 3 10 8 ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
[题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- YbtOJ#463-序列划分【二分答案,线段树,dp】
正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为\(n\)的序列\(A,B\).要求划分成若干段满足 对于任何\(i<j\),若\( ...
- HDU 4521 小明系列问题——小明序列 (线段树维护DP)
题目地址:HDU 4521 基本思路是DP.找前面数的最大值时能够用线段树来维护节省时间. 因为间隔要大于d. 所以能够用一个队列来延迟更新,来保证每次询问到的都是d个之前的. 代码例如以下: #in ...
随机推荐
- python保留关键字和常用关键字
python保留关键字和常用关键字如下: 上图是python3中的关键字,python2.7中的关键字部分会有区别,具体在自己打印输出查看: import keyword print ' '.join ...
- 「题目代码」P1007~P1012(Java)
1007 C基础-计负均正 import java.util.*; import java.io.*; public class Main { public static void main(Stri ...
- 06-Mysql数据库----表的操作
06-表的操作 本节掌握 存储引擎介绍(了解) 表的增删改查 一.存储引擎(了解) 前几节我们知道mysql中建立的库===>文件夹,库中的表====>文件 现实生活中我们用来存储数据 ...
- HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description A sequence Sn is defined as:Where a, b, n, m are positive integers.┌x┐is the cei ...
- RMQ问题+ST算法
一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...
- 查看lwjgl常用状态的值
在遇到状态值较多较复杂的情况,可以选择使用GL11.glIsEnabled()或者GL11.glGet()函数来查看状态机值,以下是常用值: public static void printOpenG ...
- 个人作业4——alpha阶段个人总结1
一.个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 总体来说,这次的alpha并不是很顺利,编程是基础,如果对语言不是很熟悉的话,一个团队是很难开发出什么东 ...
- 从零开始配置Jenkins(一)——基本配置
[背景] 由于项目变动,需要重新搭建jenkins环境,并在新搭建的平台下进行配置.之前,小编只是照猫画虎的用jenkins手动构建,虽然也维护过一段时间,但对于其中的原理并不是很了解.这下可好了,学 ...
- 【Python】- 如何使用Visual Studio 2013编写python?
安装Visual Studio 2013 1.VS2013下载安装略 安装python2.7 1.从官网下载python2.7,下载地址:https://www.python.org/getit/ ...
- C++ 点
2017/12/23 scoped_ptr类型的指针,只能在一个namespace中使用 1) 怎么查看元素在set中是否存在 1) istringstream类用于执行C++风格的串流的输入操作. ...