【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 ...
随机推荐
- FPGA等占空比奇偶分频和半整数分频
1. 偶数分频比较简单,如果分频系数是N(如果N是偶数,那么N/2是整数),那么在输入时钟的每隔N/2个周期时(计数器从0到N/2-1),改变输出时钟的电平即可得到50%固定占空比的时钟.需要的代码如 ...
- es6中类的注意事项
class Circle { constructor(radius) { this.radius = radius; Circle.circlesMade++; }; static draw(circ ...
- NOI中“大整数加法”问题不能AC的解决建议
一.检查输入000和00相加是否出结果. 二.数组不要开小了,亲测256的数组不够.推荐1024. 附录AC程序: 如果不能AC请将256改为1024,255改为1023. #include &l ...
- mysql字段名与关键字重复解决办法
mysql 关键字与字段名相同,插入或者修改里会报错 解决办法: 1.改字段名,如果库里面表结构关系不复杂,修改字段名就解决 2.在插入或者修改字段时,字段名加上 ` 包上,注意:这里不是引号,是英 ...
- python3.6 新特性学习
#支持类型提示 typing { def greeting(name: str) -> str: return 'Hello ' + name #在函数greeting中,参数名称的类型为str ...
- 关于2018年东南大学Robomaster算法组工作的总结
笔者在写作时,为东南大学机器人俱乐部下Robomaster大赛SUPER NOVA战队算法组的负责人之一(这名字写起来好长).而SUPER NOVA战队则于2018年5月19日正式结束了中部分区赛,获 ...
- 启动 SQL Server 管理 Studio 在 SQL Server 2008R2 中的错误消息:"无法读取此系统上以前注册的服务器的列表" 解决方法
问题: 服务器被人直接停掉,重启后,发现sqlserver2008r2 启动管理器报错: "无法读取此系统上以前注册的服务器的列表" 如图: 点击继续,进入后: 解决方法: 点击上 ...
- POJ 3565 Ants(最佳完美匹配)
Description Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on ...
- 使用ZSetOperations(有序)操作redis
方法 c参数 s说明 Boolean add(K key, V value, double score); K key:集合key V value:key对应的值 double score:分数 向 ...
- linux下easy_install的安装与使用详解
Python中的easy_install工具用起来非常好用,它的作用类似于Php中的pear,或者Ruby中的gem,或者Perl中的cpan. 1.easy_install安装 如果想使用easy_ ...