金题大战Vol.0 B、序列
金题大战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、序列的更多相关文章
- 金题大战Vol.0 C、树上的等差数列
金题大战Vol.0 C.树上的等差数列 题目描述 给定一棵包含\(N\)个节点的无根树,节点编号\(1-N\).其中每个节点都具有一个权值,第\(i\)个节点的权值是\(A_i\). 小\(Hi\)希 ...
- 金题大战Vol.0 A、凉宫春日的叹息
金题大战Vol.0 A.凉宫春日的叹息 题目描述 给定一个数组,将其所有子区间的和从小到大排序,求第 \(k\) 小的是多少. 输入格式 第一行两个数\(n\),$ k\(,表示数组的长度和\)k$: ...
- 土题大战Vol.0 A. 笨小猴 思维好题
土题大战Vol.0 A. 笨小猴 思维好题 题目描述 驴蛋蛋有 \(2n + 1\) 张 \(4\) 星武器卡片,每张卡片上都有两个数字,第 \(i\) 张卡片上的两个数字分别是 \(A_i\) 与 ...
- 火题大战Vol.0 B 计数DP
火题大战Vol.0 B 题目描述 \(n\) 个沙茶,被编号 \(1\)~$ n$.排完队之后,每个沙茶希望,自己的相邻的两人只要无一个人的编号和自己的编号相差为 \(1\)(\(+1\) 或\(-1 ...
- 水题大战Vol.3 B. DP搬运工2
水题大战Vol.3 B. DP搬运工2 题目描述 给你\(n,K\),求有多少个\(1\)到\(n\) 的排列,恰好有\(K\)个数\(i\) 满足\(a_{i-1},a_{i+1}\) 都小于\(a ...
- 火题大战Vol.1 A.
火题大战Vol.1 A. 题目描述 给定两个数\(x\),\(y\),比较\(x^y\) 与\(y!\)的大小. 输入格式 第一行一个整数\(T\)表示数据组数. 接下来\(T\)行,每行两个整数\( ...
- [火星补锅] 水题大战Vol.2 T2 && luogu P3623 [APIO2008]免费道路 题解
前言: 如果我自己写的话,或许能想出来正解,但是多半会因为整不出正确性而弃掉. 解析: 这题算是对Kruskal的熟练运用吧. 要求一颗生成树.也就是说,最后的边数是确定的. 首先我们容易想到一个策略 ...
- [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)
前言: 当时考场上并没有想出来...后来也是看了题解才明白 解析: 大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化.(这个性质挺重要的,我之前没看出来) 所以就可以 ...
- MathExam小学一二年级计算题生成器V1.0
MathExam小学一二年级计算题生成器v1.0 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning ...
随机推荐
- JAVA集合二:HashMap和Hashtable
参考链接: HOW2J.CN HashMap HashMap实现了JAVA的Map接口,类似于C++的STL框架的Map,是存储键值对的数据结构.键(key)是唯一的,但值(value)可以重复,如果 ...
- CSS和JS实现文本溢出显示省略号
本文记录实现文本溢出显示省略号的几种方式. 单行文本 三行CSS代码实现: overflow: hidden; // 文本溢出隐藏 text-overflow: ellipsis; // 显示省略号 ...
- idea 导入eclipse play1.2.7项目
1.play eclipsify #myapp 转为eclipse目录结构 2.导入eclipse,一路next. 3.新增个Application -Xms1536m-Xmx2048m-Xdebug ...
- .Net Core缓存组件(MemoryCache)【缓存篇(二)】
一.前言 .Net Core缓存源码 1.上篇.NET Core ResponseCache[缓存篇(一)]中我们提到了使用客户端缓存.和服务端缓存.本文我们介绍MemoryCache缓存组件,说到服 ...
- Problem H: 质心算法
Description 在很多应用中,需要对某个目标进行定位.比如对于一个未知坐标的点A,假定已知A点与N个点相邻,且已知N个相邻点的坐标,则可取N个点的质心作为A点坐标的一个估计值. 所谓质心,就是 ...
- C++的vector的使用方法
vector c++的vector的使用方法,创建,初始化,插入,删除等. #include "ex_vector.h" #include <iostream> #in ...
- LQB2013A02排它平方数
这个题方向其实还算好找,就是枚举嘛 (这是一个填空题,所以六个for嵌套也无所谓,因为毕竟emmmm,不看时间) 这里是判断的代码: 需要把数字转化成字符串 void i2s(int x,string ...
- 12-21 Request庫
- MySQL 笔记 —— 中文乱码解决、修改mysql服务端编码
https://blog.csdn.net/qq_19865749/article/details/79235422
- 区块链钱包开发 - USDT - 一、Omni本地钱包安装
背景 Tether(USDT)中文又叫泰达币,是一种加密货币,是Tether公司推出的基于稳定价值货币美元(USD)的代币Tether USD,也是目前数字货币中最稳定的币,USDT目前发行了两种代币 ...