【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 ...
随机推荐
- 保证IO流不出错
package com.io.demo1; import java.io.FileInputStream;import java.io.IOException; /** * 测试IO * io流,输入 ...
- 读取Excel错误,未在本地计算机上注册 oledb.4.0
以前写的一个读取Excel的程序,现在在另外一台机器上运行,竟然报错说"未在本地计算机上注册 oledb.4.0" 最后才知道,原来是因为现在运行的那台电脑 ...
- 激活Windows Server 2008R2
1. 用管理员身份运行mini-KMS_Activator_v1.053_ENG 2. 点击倒数第二个菜单Activation Windows VL 选择数字1 下一步选择Y 不管后面报不报错 3. ...
- 国际电话区号SQL
CREATE TABLE `phone_prefix` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `country` varchar(30) N ...
- Ubuntu下使用Git_2
接着上一篇的写,这里练习一下git clone 指令 指令格式 $ git clone <repository> <directory> <respository> ...
- linux下安装redis及主从配置
安装比较简单,确保linux安装有gcc # gcc -v 查看gcc版本,如果没有yum安装即可 安装开始 1.redis-3.2.8.tar.gz 上传至服务器 (百度网盘:http://pan. ...
- C# 结构类型与类的区别
结构类型是值类型:类是引用类型: 内存位置不同,结构类型在应用程序的堆栈中:类对象在托管中: 是否改变源对象
- Python杂篇
一:文件保存 def save_to_file(file_name, contents): fh = open(file_name, 'w') fh.write(contents) fh.close( ...
- android扁平化ProgressBar--progressWheel
ProgressWheel是git是一个开源项目,为开发者提供一个扁平化的ProgressBar,并可对其进行深度定制 1,将ProgressWheel的源码拷贝到项目中 public class ...
- 【linux】linux中tree的安装
# 2018/7/29 10:17:46测试成功! 一 Tree命令简介 tree是一种递归目录列表命令,产生一个深度缩进列表文件. 二 Tree命令安装 1.下载安装包,地址:http://mama ...