金题大战Vol.0 B、序列

题目描述

给定两个长度为 \(n\) 的序列\(a\), \(b\)。

你需要选择一个区间\([l,r]\),使得\(a_l+…+a_r>=0\)且\(b_l+…+b_r>=0\)。最大化你选择的区间长度。

输入格式

第一行一个整数\(n\),第二行\(n\)个整数\(a_1-a_n\),第三行n个整数\(b_1-b_n\)。

输出格式

一行一个整数表示\(max(r-l+1)\)。保证至少有一个区间满足条件。

样例

样例输入

5

2 -4 1 2 -2

-2 3 1 -3 1

样例输出

1

数据范围与提示

对于\(20\%\) 的数据,\(n<=5000\)。

对于\(60\%\) 的数据,\(n<=10^5\)。

对于\(100\%\) 的数据,\(1<=n<=10^6,|ai|, |bi|<=10^9\)。 数据有一定梯度。

分析

乍看上去这一道题似乎不太好处理,要同时满足下标、\(a\)、\(b\)三个条件

突破点就在于怎么把限制条件一维一维地删去

首先我们把题目中给出的数组转化成前缀和的形式

即 \(suma[r]>=suma[l],sumb[r]>=sumb[l]\)

我们将 \(suma\) 从小到大排一下序

这样我们每一次从左到右遍历,就相当于消去了一维

我们只考虑 \(sumb\) 和坐标的关系即可

这种关系我们可以用树状数组去维护,即把 \(sumb\) 的值作为树状数组的下标,把原先的编号作为树状数组的权值

这样在每次遇到一个点时,我们在树状数组中查询 \(sumb\) 比它小的最小的下标

同时更新下标为 \(sumb\) 的节点的值为当前点的编号

\(sumb\) 比较大,并且有负数,因此考虑离散化

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int a[maxn],b[maxn],n,cnt,tr[maxn];
ll suma[maxn],sumb[maxn];
struct asd{
int wz;
ll jla,jlb;
}jl[maxn];
bool cmp(asd aa,asd bb){
return aa.jla<bb.jla;
}
int lb(int xx){
return xx&-xx;
}
void ad(int wz,int val){
for(int i=wz;i<=n;i+=lb(i)){
tr[i]=min(tr[i],val);
}
}
int cx(int wz){
int ans=0x3f3f3f3f;
for(int i=wz;i>0;i-=lb(i)){
ans=min(ans,tr[i]);
}
return ans;
}
int main(){
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
int ans=1,bef,wz;
memset(tr,0x3f,sizeof(tr));
n=read();
for(register int i=1;i<=n;i++){
a[i]=read();
suma[i]=suma[i-1]+(ll)a[i];
}
for(register int i=1;i<=n;i++){
b[i]=read();
sumb[i]=sumb[i-1]+(ll)b[i];
}
for(register int i=1;i<=n;i++){
jl[i].jla=suma[i];
jl[i].jlb=sumb[i];
if(jl[i].jla>=0 && jl[i].jlb>=0){
ans=max(ans,i);
}
jl[i].wz=i;
}
sort(jl+1,jl+1+n,cmp);
sort(sumb+1,sumb+1+n);
cnt=unique(sumb+1,sumb+1+n)-sumb-1;
for(int i=1;i<=n;i++){
wz=lower_bound(sumb+1,sumb+cnt+1,jl[i].jlb)-sumb;
bef=cx(wz);
if(bef>=jl[i].wz){
ad(wz,jl[i].wz);
continue;
}
ans=max(ans,jl[i].wz-bef);
ad(wz,jl[i].wz);
}
printf("%d\n",ans);
return 0;
}

金题大战Vol.0 B、序列的更多相关文章

  1. 金题大战Vol.0 C、树上的等差数列

    金题大战Vol.0 C.树上的等差数列 题目描述 给定一棵包含\(N\)个节点的无根树,节点编号\(1-N\).其中每个节点都具有一个权值,第\(i\)个节点的权值是\(A_i\). 小\(Hi\)希 ...

  2. 金题大战Vol.0 A、凉宫春日的叹息

    金题大战Vol.0 A.凉宫春日的叹息 题目描述 给定一个数组,将其所有子区间的和从小到大排序,求第 \(k\) 小的是多少. 输入格式 第一行两个数\(n\),$ k\(,表示数组的长度和\)k$: ...

  3. 土题大战Vol.0 A. 笨小猴 思维好题

    土题大战Vol.0 A. 笨小猴 思维好题 题目描述 驴蛋蛋有 \(2n + 1\) 张 \(4\) 星武器卡片,每张卡片上都有两个数字,第 \(i\) 张卡片上的两个数字分别是 \(A_i\) 与 ...

  4. 火题大战Vol.0 B 计数DP

    火题大战Vol.0 B 题目描述 \(n\) 个沙茶,被编号 \(1\)~$ n$.排完队之后,每个沙茶希望,自己的相邻的两人只要无一个人的编号和自己的编号相差为 \(1\)(\(+1\) 或\(-1 ...

  5. 水题大战Vol.3 B. DP搬运工2

    水题大战Vol.3 B. DP搬运工2 题目描述 给你\(n,K\),求有多少个\(1\)到\(n\) 的排列,恰好有\(K\)个数\(i\) 满足\(a_{i-1},a_{i+1}\) 都小于\(a ...

  6. 火题大战Vol.1 A.

    火题大战Vol.1 A. 题目描述 给定两个数\(x\),\(y\),比较\(x^y\) 与\(y!\)的大小. 输入格式 第一行一个整数\(T\)表示数据组数. 接下来\(T\)行,每行两个整数\( ...

  7. [火星补锅] 水题大战Vol.2 T2 && luogu P3623 [APIO2008]免费道路 题解

    前言: 如果我自己写的话,或许能想出来正解,但是多半会因为整不出正确性而弃掉. 解析: 这题算是对Kruskal的熟练运用吧. 要求一颗生成树.也就是说,最后的边数是确定的. 首先我们容易想到一个策略 ...

  8. [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)

    前言: 当时考场上并没有想出来...后来也是看了题解才明白 解析: 大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化.(这个性质挺重要的,我之前没看出来) 所以就可以 ...

  9. MathExam小学一二年级计算题生成器V1.0

    MathExam小学一二年级计算题生成器v1.0 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning ...

随机推荐

  1. JAVA基础系列:JDK目录结构

    0. 名词解释 SDK: Softeare Development Kit,用于开发JavaEE,包括JDK. JDK: Java Development Kit,java开发工具包,包括Java编译 ...

  2. 七牛云如何绑定二次验证码_虚拟MFA_两步验证_谷歌身份验证器?

    一般情况下,点账户名——账户设置——安全设置,即可开通两步验证 具体步骤见链接  七牛云如何绑定二次验证码_虚拟MFA_两步验证_谷歌身份验证器?   二次验证码小程序(官网)对比谷歌身份验证器APP ...

  3. 程序员每日一乐:html动态烟花设计 3D

    3D版烟花 效果图:file:///C:/Users/QianXin/Desktop/3D%E7%83%9F%E8%8A%B1.html 经过一天的的工作或者学习是否感到枯燥乏味?现在的你是否想找些乐 ...

  4. 7.20试机测 T3 阶乘之和 暴力AC题解

    7.20试机测  T3 阶乘之和 暴力AC题解 题外话:此乃本蒟蒻发表的第一篇题解,大家多多关照,支持一下,谢谢 题面 3.阶乘之和(sum.pas/in/out) 问题描述: 给定一个非负整数 n, ...

  5. 完成的设备扫描项目的几个关键程序,包括activity之间的转换

    module 的 gradle.build最后三行的compile 是关键dependencies { implementation fileTree(dir: 'libs', include: [' ...

  6. Android复习准备

    1. 四大组件是什么? Activity(活动):用于表现功能 Service(服务):后台运行服务,不提供界面呈现 BroadcastReceiver(广播接收器):用来接收广播 ContentPr ...

  7. nrm安装使用(mac)

    在开发工作中时常有需要切换npm源的需求以及更换node版本的情况,这两种情况都有对应的管理器来使用 一.nrm nrm是一个npm源管理工具,使用它可以快速切换npm源. 1.nrm安装(全局安装) ...

  8. windows 下安装YApi及集成Idea的YapiUpload

    一准备工具 Mongodb Node和npm 二文档地址 https://hellosean1025.github.io/yapi/ 三安装步骤 1.安装Mongodb,请参考 2.安装Node,请参 ...

  9. python学习笔记1 -- 函数式编程之高阶函数 使用函数作为返回值

    使用函数作为返回值,看起来就很高端有木有,前面了解过函数名本身就是一个变量,就比如abs()函数,abs只是变量名,而abs()才是函数调用,那么我们如果把ads这个变量作为返回值返回会怎么样呢,这就 ...

  10. 如何查看Oracle的版本

    本人使用的软件是DataGrip 在控制台输入 select * from v$version;