原题题意

给出长度为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]的更多相关文章

  1. 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 ...

  2. 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 ...

  3. Quality 是什么?

    Quality 是什么? 通常,我们谈及 Quality(质量)时,最常见的问题就是:Quality 是什么? 有很多业界先驱和研究人员已经回答了这个问题,我在这里并不会再给出一个新的答案.在学习总结 ...

  4. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  5. Unit Testing with NSubstitute

    These are the contents of my training session about unit testing, and also have some introductions a ...

  6. 超强语感训练文章(Provided by Rocky teacher Prince)

    Content: Class1 My name is Prince Class2 Welcome to our hotel Class3 We’re not afraid of problems Cl ...

  7. Common Pitfalls In Machine Learning Projects

    Common Pitfalls In Machine Learning Projects In a recent presentation, Ben Hamner described the comm ...

  8. 软件工程课程作业(三)--四则运算3(C++)

    伙伴链接:http://www.cnblogs.com/haoying1994/ 一.设计思路 在此前程序拥有的功能:加减有无负数,除法有无余数以及算式可定制的功能的基础上,此次程序又添加了算式结果的 ...

  9. 单元测试--四则运算2程序(c++)

    源代码: //2016 3.6 Cheng Qiqin //四则运算改进 #include <iostream> #include<ctime> #include<cst ...

随机推荐

  1. Django进阶之中间件

    中间件简介 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在djang ...

  2. rabbitmq延迟队列demo

    1. demo详解 1.1 工程结构: 1.2 pom 定义jar包依赖的版本.版本很重要,rabbit依赖spring,两者必须相一致,否则报错: <properties> <sp ...

  3. js 二维数组 for 循环重新赋值

    javascript 二维数组的重新 组装 var arr = [[1,2],[3,4],[5,6],[7,8]]; var temp = new Array(); for(var i= 0 ;i&l ...

  4. flutter key

    随意点开一个Widget,就会发现,可以传递一个参数Key.那这个Key到底是干啥子,有什么用呢? Flutter是受React启发的,所以Virtual Dom的diff算法也参考过来了(应该是略有 ...

  5. K8S学习笔记之k8s日志收集实战

    0x00 简介 本文主要介绍在k8s中收集应用的日志方案,应用运行中日志,一般情况下都需要收集存储到一个集中的日志管理系统中,可以方便对日志进行分析统计,监控,甚至用于机器学习,智能分析应用系统问题, ...

  6. jQuery 筛选器1

    jQuery 筛选器1 筛选器1: 在选择器选择的基础上在选择一次 // 当前点击的标签$(this) $(this) // .next() 获取当标签的下一个标签 $(this).next(); / ...

  7. Docket 使用命令

    Docket 使用命令 查 # 查询当前可以下载的镜像 docker search httpd  |_ NAME:镜像仓库源的名称 |_ DESCRIPTION:镜像的描述 |_ OFFICIAL:是 ...

  8. Springboot 上传excel并解析文件内容

    最近在做一个物业的系统,需要通过excel上传业主的信息,解析并入库. 参考:https://www.cnblogs.com/jyyjava/p/8074322.html 话不多说,直接上核心代码 i ...

  9. [c/c++] programming之路(20)、字符串(一)

    一.字符串 #include<stdio.h> #include<stdlib.h> void main(){ ]="notepad"; printf(&q ...

  10. Python3 tkinter基础 OptionMenu 将list导入下拉列表中

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...