>传送门<

前言


这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维。(博客分析那块写的啰里吧嗦又改了很多废话)

题意


在一个长度为$10^{9}$的序列上,保证只有$n(n<10^{6})$个区间等于$1$,且$1$的个数小于10^{7},其他位置全部为$-1$,求区间和$>0$的区间数量

分析


题目意思很简单,对不对~ 那接下来我们就思考下该怎么做这题。

考虑做前缀和,问题就转化成$sum[i]-sum[j] > 0$的对数

举个栗子,比如序列$\left \{ -1,-1,-1,1,1,1,1 \right \}$,对应的前缀和为$\left \{ -1,-2,-3,-2,-1,0,1 \right \}$

那么$-1>-2$,中间的$\left \{ -1,-1,1,1,1 \right \}$区间和$>0$

由于数据范围较大不可能对整个数组前缀和进行处理,我们注意到能被1覆盖的区间长度最多有$3e7$, 因为区间向前,向后最多可以覆盖$1e7$,所以加起来就是$3e7$,这是本题求解的关键。

所以我们可以处理一下区间,让它尽可能的延伸而又不至于小于$0$,之后我们只需要计算在当前点有多少前面点的前缀和小于它就行了。这样我们就可以用树状数组来求,可范围太大了我们只能用别的方法(不甘心的我用树状数组试了下果然超时)

Code

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e7+;
int l[maxn], r[maxn], n;
int L[maxn],R[maxn];
int num[maxn*];
int main()
{
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d%d", &l[i], &r[i]);
r[] = R[] = -, l[n+] = 1e9;
int len=;
for(int i = ; i <= n; i++){
len += r[i]-l[i]+;
R[i] = min(r[i]+len,l[i+]-);
len -= l[i+]-r[i]-;
if(len<) len=;
}
len=;
for(int i = n; i > ; i--){
len += r[i]-l[i]+;
L[i] = max(l[i]-len,r[i-]+);
len -= l[i]-r[i-]-;
if(len<) len=;
} int now = 1e7+;
num[now] = ;
ll sum = , ans = ;
for(int i = ; i <= n; i++){
for(int j = max(L[i],R[i-]+); j <= R[i]; j++){
if(j>=l[i]&&j<=r[i]){
sum += num[now];
num[++now]++;
}else{
sum -= num[--now];
num[now]++;
}
ans += sum;
}
}
printf("%lld",ans);
return ;
} /*
now记录的是当前的前缀和,sum记录前缀和小于now的数量,num数组记录的所有前缀和对应的数目。
假如j对应的数字是1,num[++now]显然应该加1,由于此时前缀和比上次要大,那么执行这一步操作前我们应该先把sum加上num[now];
假如j对应的数字是-1,num[--now]也当然加1,这时候前缀和比上次要小,执行完这步后sum应当减去此时和now相等的前缀和数量就得到比now小的前缀和数量。
*/

可能有的人会跟我有一样的疑惑,一但中间出现“断层”怎么办?也即是中间有非常多的$-1$导致相邻两端不能相连。你仔细想想,其实对于我们这种做法没有任何影响,我们只处理对答案有贡献的区间的点。你可能会说如果”断层“的话前缀和应该重新计算,但是实际上我们是在判断$sum[i]-sum[j] > 0$即$sum[i]>sum[j]$,从不从$0$开始算我们并不关心,我们只在乎他们的相对大小,这里一定要好好想一想!!!


参考资料:

https://www.cnblogs.com/ckxkexing/p/11219612.html

https://blog.csdn.net/qq_41785863/article/details/98469396

https://www.cnblogs.com/bpdwn-cnblogs/p/11252185.html

2019牛客暑期多校训练营(第二场)J-Subarray(思维)的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  3. 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学

    LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...

  4. 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路

    LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...

  5. 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心

    LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...

  6. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  7. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  8. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  9. 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)

    layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...

  10. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

随机推荐

  1. spring boot 学习笔记(二)之打包

    一.叙述 spring boot 在 pom 中可以配置成  packaging 为 jar ,这样打包出来的就是一个 jar 包,可以通过 Java 命令直接运行, Java 命令为: java - ...

  2. 【POJ - 1862】Stripies (贪心)

    Stripies 直接上中文了 Descriptions 我们的化学生物学家发明了一种新的叫stripies非常神奇的生命.该stripies是透明的无定形变形虫似的生物,生活在果冻状的营养培养基平板 ...

  3. Git命令备忘录

    目录 前言 基本内容 开始之前 基础内容 远程仓库 分支管理 前言 Git在平时的开发中经常使用,整理Git使用全面的梳理. 基本内容 开始之前 请自行准备好Git工具以及配置好Git的基本配置 基础 ...

  4. vue+Elment-UI,修改element组件样式

    在用vue开发项目过程中,我们总是避免不了的会使用到elementUI,它里面提供的一些组件都为我们的开发带来了很大的便利,但是,当有时候我们需要使用这些组件的同时又要修改下组件的UI样式的话,我们该 ...

  5. Docker笔记(七):常用服务安装——Nginx、MySql、Redis

    开发中经常需要安装一些常用的服务软件,如Nginx.MySql.Redis等,如果按照普通的安装方法,一般都相对比较繁琐 —— 要经过下载软件或源码包,编译安装,配置,启动等步骤,使用 Docker ...

  6. git bash 初始化配置

    这里只针对 windows 下,使用git 时的一些初始配置 1. git bash 安装 下载地址: https://git-for-windows.github.io/ 根据提示,一步步安装即可 ...

  7. 同时启动多个tomcat,端口修改

    所用Tomcat服务器都为zip 版,非安装版.以 tomcat8 为例: 安装第二个Tomcat完成后,打开 tomcat/conf/server.xml 文件,查找以下三处: 1. 修改http访 ...

  8. ride.py在运行python3.×版本后导致无法运行及解决办法

    最近一直在自学python自动化,网上看到rf框架挺适合初学自动化测试,于是通过虫师的搭建了rf框架, 但是在使用过程中遇到了一个问题,在网上没有找到明确解决办法于是想到记录一下 之前为了搭建rf框架 ...

  9. 第十五章 LVM管理和ssm存储管理器使用 随堂笔记

    第十五章 LVM管理和ssm存储管理器使用 本节所讲内容: 15.1 LVM的工作原理 15.2 创建LVM的基本步骤 15.3 实战-使用SSM工具为公司的邮件服务器创建可动态扩容的存储池 LVM的 ...

  10. MySQL数据库基本知识(理论总结)

    定义:数据库就是一个文件系统,通过sql语句来获取数据 关系型数据库:关系型数据库存放的是实体时间的关系,在数据库层面来看就是存放的是表和表之间的关联关系 常见的关系型数据库   MySQL    D ...