2019牛客暑期多校训练营(第二场)J-Subarray(思维)
前言
这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维。(博客分析那块写的啰里吧嗦又改了很多废话)
题意
在一个长度为$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(思维)的更多相关文章
- 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...
- 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论
LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...
- 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学
LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...
- 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路
LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...
- 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心
LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...
- 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心
LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...
- 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP
LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
- 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)
layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
随机推荐
- Lexical or preprocessor 'XXX/XXX.h' issue file not found
最近做第三方登录,引入了第三库,结果就出来个这个问题.如下图所示: 刚开始编译运行都没问题,可下次再打开时就报这个错误…… 一个比较弱智的解决办法: 1. 删除第三方库文件(删除到垃圾箱,而且还要在文 ...
- 对vue中nextTick()的理解及使用场景说明
异步更新队列: 首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的. 即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新 ...
- 佳木斯集训Day5
今天是ACM赛制...本来可以400的,结果毒瘤T2模拟硬生生卡掉了我90分 T1是个大水题,找规律,5分钟AC没啥压力 #include <bits/stdc++.h> #define ...
- Cocos经典游戏教程之仿皇室战争
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- 0x02 递推与递归
[例题]CH0301 递归实现指数型枚举 #include <iostream> #include <cstdio> #include <algorithm> #i ...
- PHP 的一些开发规范
均需要遵守 PSR规范 变量命名 不用拼音 驼峰或下划线风格要一致 单词要有意义 不用关键字 常量全大写用下划线连接 代码注释 尽量让代码可读性提高,减少代码上的注释 函数头部可以描述参数和返回值及功 ...
- JAVA基础知识(八)值传递与引用传递
值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...
- Hibernate的执行流程
Hibernate框架的工作流程 1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件 2.由hibernate.cfg.xml中的&l ...
- 通过Blazor使用C#开发SPA单页面应用程序(3)
今天我们来看看Blazor开发的一些基本知识. 一.Blazor组件结构 Blazor中组件的基本结构可以分为3个部分,如下所示: //Counter.razor //Directives secti ...
- 洛谷 P1939 矩阵加速(数列)
题意简述 \(a[1]=a[2]=a[3]=1\) \(a[x]=a[x−3]+a[x−1](x>3)\) 求a数列的第n项对1000000007取余的值. 题解思路 矩阵加速 设\[ F=\b ...