CF727F [Polycarp's problems] & [EX_Polycarp's problems]
原题题意
给出长度为n的有序数组,m次询问,每次给出一个正整数x。你要删除数组中最少的元素,使得数组中的前缀和+x都为非负整数。允许离线,n≤750,m≤200,000。
原题思路
首先注意到,x能成功通过测试当且仅当前缀和中最小的数≥x。
将询问从大到小排个序,对于一个新的询问,每次尝试从数组中删除最优的一个数,使得成功的机会更大。
何为最优?我们注意到,ai只会对后面的数造成影响。设当前前缀和最小为now,fi为前i个前缀和中最小的数,则答案会增加 max { min { now-ai , fi-1 } } (请注意后面的f囊括了now-ai顾及不到的情况)。
每次判断最小的数在哪,暴力更新,O(n3+mlogm)。
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll inf=;
const ll maxn=1E6+;
template<typename T> void read(T &x){
x=;char ch=getchar();int fh=;
while (ch<''||ch>''){if (ch=='-')fh=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
x=x*fh;
}
void write(ll x)
{
if(x==){putchar('');putchar('\n');return;}
if(x<){putchar('-');x=-x;}
ll a[],size=;
while(x){a[++size]=x%;x/=;}
for(int i=size;i>=;--i)putchar(a[i]+'');
putchar('\n');
}
ll min(ll x,ll y){return x<y?x:y;}
ll max(ll x,ll y){return x>y?x:y;}
ll n,m,a[maxn],tot,sum[maxn],ans[maxn],f[maxn];
struct query{ll pos,x;}Q[maxn];
bool cmp(query a,query b){return a.x>b.x;}
ll get()
{
ll ans=inf;
for(int i=;i<=n;++i)
{
sum[i]=sum[i-]+a[i];
ans=min(ans,sum[i]);
f[i]=min(f[i-],sum[i]);
}
return ans;
}
int main()
{
read(n);read(m);
for(int i=;i<=n;++i)
{
read(a[i]);
if(a[i]<)++tot;
}
for(int i=;i<=m;++i)
{
read(Q[i].x);
Q[i].pos=i;
}
sort(Q+,Q+m+,cmp);
int pos=;
for(int i=;i<=tot;++i)
{
ll g=get();
while(Q[pos].x+g>=&&pos<=m){ans[Q[pos].pos]=i-;++pos;}
if(g>=)break;
ll ans=-inf,pos=;
for(int j=;j<=n;++j)
{
if(min(g-a[j],f[j-])>ans)
{
ans=min(g-a[j],f[j-]);
pos=j;
}
}
a[pos]=;
}
ll g=get();
while(Q[pos].x+g>=&&pos<=m){ans[Q[pos].pos]=tot;++pos;}
for(int i=;i<=m;++i)write(ans[i]);
return ;
}
EX版本:
m,n≤1,000,000,强制在线。
思路
考虑从后往前贪心。我们先只考虑两种情况(0显然没必要考虑)。
第一种,所有的数均为负数。则每次答案必然会从最小的数删起,直到删的数的绝对值第一次大于等于询问。
第二种,只有一个数为正,其余均为负。两种情况:
第一种,加起来为仍为正,那么就不会删数。并且这一位不会对以后造成任何影响(既然都加上正数了,能到达这一位,以后肯定不会小于零)。
第二种,加起来为负。那么会贪心地选择最小的负数删,直到加起来为正。换个角度,会贪心地选择最大的负数加到正数上,直到正数为负。这样,化归为第一情况。
再将负数加入大根堆,正数不要的原因同第一种。
图画画,手算算至少能够理解。
最后得到的答案要么剩下正数,要么全是负数。这些负数取反后,从大到小排序的第i位代表了取到第i种答案,要删去1~i个数。
二分查找即可。
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll inf=;
const ll maxn=1E6+;
ll min(ll x,ll y){return x<y?x:y;}
ll max(ll x,ll y){return x>y?x:y;}
template<typename T> void read(T &x){
x=;char ch=getchar();int fh=;
while (ch<''||ch>''){if (ch=='-')fh=-;ch=getchar();}
while (ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
x=x*fh;
}
void write(ll x)
{
if(x==){putchar('');putchar('\n');return;}
if(x<){putchar('-');x=-x;}
ll a[],size=;
while(x){a[++size]=x%;x/=;}
for(int i=size;i>=;--i)putchar(a[i]+'');
putchar('\n');
}
ll n,m,a[maxn],wait[maxn],size,x;
priority_queue<ll>Q;
int main()
{
read(n);read(m);
for(int i=;i<=n;++i)read(a[i]);
for(int i=n;i>=;--i)
{
while(a[i]>=&&!Q.empty())
{
a[i]+=Q.top();
Q.pop();
}
if(a[i]<)Q.push(a[i]);
}
while(!Q.empty())
{
wait[++size]=Q.top();
Q.pop();
}
for(int i=;i<=size/;++i)swap(wait[i],wait[size-i+]);
for(int i=;i<=size;++i)wait[i]+=wait[i-];
for(int i=;i<=size;++i)wait[i]=-wait[i];
while(m--)
{
read(x);
write(lower_bound(wait,wait+size+,wait[size]-x)-wait);
}
return ;
}
CF727F [Polycarp's problems] & [EX_Polycarp's problems]的更多相关文章
- Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
Acknowledgments I would like to thank Jacob Kjome for reviewing early drafts of this document. His c ...
- Educational Codeforces Round 42 (Rated for Div. 2) A
A. Equator time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...
- Quality 是什么?
Quality 是什么? 通常,我们谈及 Quality(质量)时,最常见的问题就是:Quality 是什么? 有很多业界先驱和研究人员已经回答了这个问题,我在这里并不会再给出一个新的答案.在学习总结 ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- Unit Testing with NSubstitute
These are the contents of my training session about unit testing, and also have some introductions a ...
- 超强语感训练文章(Provided by Rocky teacher Prince)
Content: Class1 My name is Prince Class2 Welcome to our hotel Class3 We’re not afraid of problems Cl ...
- Common Pitfalls In Machine Learning Projects
Common Pitfalls In Machine Learning Projects In a recent presentation, Ben Hamner described the comm ...
- 软件工程课程作业(三)--四则运算3(C++)
伙伴链接:http://www.cnblogs.com/haoying1994/ 一.设计思路 在此前程序拥有的功能:加减有无负数,除法有无余数以及算式可定制的功能的基础上,此次程序又添加了算式结果的 ...
- 单元测试--四则运算2程序(c++)
源代码: //2016 3.6 Cheng Qiqin //四则运算改进 #include <iostream> #include<ctime> #include<cst ...
随机推荐
- Spring框架的第四天(整合ssh框架)
## Spring框架的第四天 ## ---------- **课程回顾:Spring框架第三天** 1. AOP注解方式 * 编写切面类(包含通知和切入点) * 开启自动代理 2. JDBC模板技术 ...
- CentOS 7 MariaDB-MHA
关于MHA MHA(Master High Availability)是一款开源的mysql高可用程序,目前在mysql高可用方面是一个相对成熟的解决方案.MHA 搭建的前提是MySQL集群中已 ...
- 21 python的魔法方法(转)
魔法方法 含义 基本的魔法方法 __new__(cls[, ...]) 1. __new__ 是在一个对象实例化的时候所调用的第一个方法2. 它的第一个参数是这个类,其他的参数是用来直接传递给 _ ...
- Windbg程序调试系列1-常用命令说明&示例
Windbg程序调试是.Net高级开发需要掌握的必备技能,分析内存泄露.分析高CPU.分析线程阻塞.分析内存对象.分析线程堆栈.Live Dedugging.这个领域可以说一个技能+场景化应用的结合, ...
- python 回调函数,最简单的例子
回调的英文定义: A callback is a function that is passed as an argument to another function and is executed ...
- 每天一个Linux命令 10
文件处理命令:ln命令名称:ln 命令英文原意:link语法: ln -s [原文件] [目标文件] -s 创建软连接功能描述:生成链接文件 #ln -s /etc/issue /tmp/issue. ...
- shift键有什么用?怎么用?shift键的妙用
一.当你用QQ和别人聊天时,是不是有时信息发送的特别慢呀,不要紧,只要你发信息时按shift 键信息就会很快的发送出去的! 二.当你面对一大堆窗口,却要一个一个把它们关掉时.是不是很烦啊.只要你按sh ...
- Eclipse中Tomcat v8.0 Server at localhost右键选择Properties详情页中Server Locations变灰无法编辑
Eclipse中Tomcat v8.0 Server at localhost右键选择Properties详情页中Server Locations变灰无法编辑解决办法:1.首先将Servers中部署的 ...
- Linux LVM卷组管理
Linux LVM卷组管理 由于传统的磁盘管理不能对磁盘进行磁盘管理,因此诞生了LVM技术,LVM技术最大的特点就是对磁盘进行动态管理. 由于LVM的逻辑卷的大小更改可以进行动态调整,且不会出现丢失数 ...
- mysql ERROR 1045 和2058时(28000): 错误解决办法
mysql ERROR 1045 (28000): 错误解决办法 听语音 | 浏览:54286 | 更新:2018-02-23 14:34 | 标签:mysql 1 2 3 4 5 6 7 分步阅读 ...