Distribution of books

题目传送门

解题思路

求最大值的最小值,可以想到用二分答案。

对于二分出的每个mid,要找到是否存在前缀可以份为小于等于mid的k份。先求出这n个数的前缀和sum[],dp[i]表示前i个可以构成的最大份数。初始化dp[1~n]为-1,dp[0]为0,转移方程式为:dp[i] = max(dp[j]) + 1,(sum[i] - sum[j] <= mid, dp[j] >= 0, 0 <= j < i)。如果有一个dp[i]>=k,说明mid可以,r=mid,否则l=mid+1。

但是数据范围很大,直接这么找肯定超时。所以我们要用离散化后的权值线段树来维护。对于i,我们要找的是满足sum[i] - sum[j] <= mid,即sum[j] >= sum[i] - mid的j里最大的dp[j]。所以我们用权值线段树来来维护前i-1个dp的最大值。对于每次二分都清空然后重新建树,按照插入dp[i],对于每次询问只需返回离散化后sum[j]~最大值的范围内的最大dp值。

代码如下

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll; inline int read(){
int res = 0, w = 0; char ch = 0;
while(!isdigit(ch)){
w |= ch == '-', ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -res : res;
} const int N = 200005; ll a[N], b[N];
struct T{
int l, r;
int maxx;
}tree[N<<2];
int dp[N];
int n, m; void build(int k, int l, int r)
{
tree[k].l = l;
tree[k].r = r;
tree[k].maxx = -1;
if(l >= r)
return;
int mid = (l + r) / 2;
build(2*k, l, mid);
build(2*k+1, mid + 1, r);
} void insert(int k, int x, int u)
{
if(tree[k].l == tree[k].r){
tree[k].maxx = max(tree[k].maxx, u);
return;
}
int mid = (tree[k].l + tree[k].r) / 2;
if(x <= mid)
insert(2*k, x, u);
else
insert(2*k+1, x, u);
tree[k].maxx = max(tree[2*k].maxx, tree[2*k+1].maxx);
} int query(int k, int l, int r)
{
if(tree[k].l >= l && tree[k].r <= r)
return tree[k].maxx;
int mid = (tree[k].l + tree[k].r) / 2;
int m1, m2;
m1 = m2 = -1;
if(l <= mid)
m1 = query(2*k, l, r);
if(r > mid)
m2 = query(2*k+1, l, r);
return max(m1, m2);
} bool work(ll mid, int k)
{
build(1, 0, k);
insert(1, lower_bound(b, b + k + 1, 0) - b, 0);
for(int i = 1; i <= n; i ++){
int l = lower_bound(b, b + k + 1, a[i] - mid) - b;
if(l != k + 1)
dp[i] = query(1, l, k)+ 1;
else
dp[i] = -1;
if(dp[i] == 0)
dp[i] = -1;
if(dp[i] >= m)
return true;
int x = lower_bound(b, b + k + 1, a[i]) - b;
insert(1, x, dp[i]);
}
return false;
} int main()
{
int _ = read();
while(_ --){
n = read(), m = read();
ll l = 0, r = 0;
a[0] = b[0] = 0;
for(int i = 1; i <= n; i ++){
ll x = read();
if(x < 0)
l += x;
if(x > 0)
r += x;
a[i] = a[i - 1] + x;
b[i] = a[i];
}
sort(b, b + n + 1);
int k = unique(b, b + n + 1) - b - 1;
ll mid = (l + r) / 2;
while(l < r){
if(work(mid, k))
r = mid;
else
l = mid + 1;
mid = (l + r) / 2;
}
printf("%lld\n", mid);
}
return 0;
}

2019杭电多校第三场hdu6606 Distribution of books(二分答案+dp+权值线段树)的更多相关文章

  1. [2019杭电多校第三场][hdu6606]Distribution of books(线段树&&dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6606 题意为在n个数中选m(自选)个数,然后把m个数分成k块,使得每块数字之和最大的最小. 求数字和最 ...

  2. 2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)

    K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明 ...

  3. [2019杭电多校第三场][hdu6609]Find the answer(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 大致题意是求出每个位置i最小需要将几个位置j变为0(j<i),使得$\sum_{j=1}^ ...

  4. [2019杭电多校第三场][hdu6608]Fansblog

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6608 大致题意是比p小的最大素数q,求q!%p的值. 由威尔逊定理开始推: $(p-1)!\equiv ...

  5. 2019杭电多校第三场hdu6608 Fansblog(威尔逊定理)

    Fansblog 题目传送门 解题思路 Q! % P = (P-1)!/(P-1)...(Q-1) % P. 因为P是质数,根据威尔逊定理,(P-1)!%P=P-1.所以答案就是(P-1)((P-1) ...

  6. 2019杭电多校第三场hdu6609 Find the answer(线段树)

    Find the answer 题目传送门 解题思路 要想变0的个数最少,显然是优先把大的变成0.所以离散化,建立一颗权值线段树,维护区间和与区间元素数量,假设至少减去k才能满足条件,查询大于等于k的 ...

  7. HDU多校第三场 Hdu6606 Distribution of books 线段树优化DP

    Hdu6606 Distribution of books 题意 把一段连续的数字分成k段,不能有空段且段和段之间不能有间隔,但是可以舍去一部分后缀数字,求\(min(max((\sum ai ))\ ...

  8. 2019年杭电多校第三场 1011题Squrirrel(HDU6613+树DP)

    题目链接 传送门 题意 给你一棵无根树,要你寻找一个根节点使得在将一条边权变为\(0\)后,离树根最远的点到根节点的距离最小. 思路 本题和求树的直径很像,不过要记得的东西有点多,且状态也很多. \( ...

  9. 2019年杭电多校第三场 1008题Game(HDU6610+带修改莫队+Nim博弈)

    题目链接 传送门 题意 给你\(n\)堆石子,每堆有\(a_i\)堆石子,\(q\)次操作: 在\([L,R]\)内有多少个子区间使得\(Alice\)(先手)在\(Nim\)博弈中获胜: 交换\(a ...

随机推荐

  1. centos 安装 Lamp(Linux + Apache + PHP) 并安装 phpmyadmin

    来源:http://www.laozhe.net/302.html 一般情况下,安装的都是最新的正式版,除非你有特殊需求,要安装指定的版本,本文暂不讨论.从最基础的开始,一点点完成一个可用的 Linu ...

  2. eclipse 集成 STS 插件

    eclipse 集成 STS 插件 想新建一个 Spring Boot 工程,发现没有,如图:(展示的是集成之后的) eclipse 要和 sts 版本对应的,进入http://spring.io/t ...

  3. Backdoor CTF 2013 :电子取证250

    0x00题目 h4x0r厌烦了你对他的城堡的所有攻击,所以他决定报复攻击你,他给你发来一封带有图片的邮件作为警告,希望你能找出他的警告消息:-) 消息的MD5值就是flag. 图片如下: 0x01解题 ...

  4. 06、python的基础-->编码小知识

    1.编码类型ascii A : 00000010 8位 一个字节 unicode A : 00000000 00000001 00000010 00000100 32位 四个字节 中:00000000 ...

  5. ArangoDB 的graph查询

    一个graph包含vertices 和edges.edges被存储在edges document当中.vertices可以是document collection 中的document也可以是edge ...

  6. HashMap源码解析笔记

    首先简单介绍下HashMap: 1.HashMap有三种数据结构:数组,链表,红黑树. 2.HashMap是非线程安全的 3.HashMap存储的内容是键值对(key-value)映射,key.val ...

  7. CF1228F

    写了一个特别麻烦的做法 首先一共有三种情况:1.删掉一个叶子,2.删掉根的一个儿子,3.其他的节点 第一种情况会有两个度数为2的节点,第二种情况没有度数为2的节点,第三种情况会有一个度数为4的节点 然 ...

  8. js保留两位小数的方法

    js保留两位小数的方法如下 1.toFixed()方法 需注意,保留两位小数,将数值类型的数据改变成了字符串类型 2.Math.floor(),不四舍五入 ,向下取整 注意,不改变数据类型 3.字符串 ...

  9. react使用总结

    1.拿到页面首先需要设计好,每个组件该怎么实现,划分好组件可以减少重复代码,有的时候需要和后端确认才能形成正确的划分 2.页面上的需要展示的数据都是由后端数据而来,所以任何增删改查的数据都要从后端重新 ...

  10. cenos7 下数据库相关操作

    1.Linux Centos7下如何确认MySQL服务已经启动 https://www.cnblogs.com/qianzf/p/7082484.html 2.CentOS 7上安装MySQL并配置远 ...