Codeforces 612D 前缀和处理区间问题
传送门:http://codeforces.com/problemset/problem/612/D
(转载请注明出处谢谢)
题意:
给出数字n和k,n表示接下来将输入n个在x轴上的闭区间[li,ri],找出被包含了至少k次的点,并求由这些点组成的连续区间的数目,并使该数目最小。输出该数目并将区间从左到右(x的正方向)输出。
比如样例1,给出区间[0,5],[-3,2],[3,8],那么被覆盖了至少两次的区间就是[0,2],[3,5],有两个。
解题思路:
处理区间覆盖,一上来就想到了前缀和,普通前缀和处理的话,以数值为下标,然后开一个标记数组,每次对于区间[l,r],tmp[l]++,tmp[r+1]--,这样求前缀和数组s后,s[i]即为i被覆盖的次数,因此只需要如此操作一遍后,O(n)扫一遍,连续的s[x]>=k的,就为一个区间,记录输出即可。
随后注意到,l和r的范围在[-1e9,1e9],开不了数组,但n只为1e6,每次输入最多2e6个数字,因此采用离散化处理。将输入是数字排序后,扫一遍所有区间,每次用lower_bound来求它所在的位置,因为一定存在,所以得到的下标一定是该数字的第一个下标(如果有重复,则为第一个该数字的下标)。
在运行样例时,发现出来的结果不对。留意到是因为此时运行出来的前缀和数组s[]和想要的不一样。一般情况下,前缀和处理区间覆盖问题时“tmp[l]++,tmp[r+1]--”中的l和r指的是数值,而离散化后指的是它的下标,在处理的时候就会发生冲突。
为了解决这个冲突,只要给每个数字都多“复制”一次就可以了,因为此时tmp[r+1]中的r+1所指是一个“多余”的位置,就不会出现冲突的情况。(语言表述有点无力,下面以第一个样例为例)
区间[0,5],[-3,2],[3,8],输入后为a[]={-3,0,2,3,5,8},然后按上述所说求前缀和数组为s[]={1,2,2,2,2,1}。复制后,a[]={-3,-3,0,0,2,2,3,3,5,5,8,8},前缀和数组为s[]={1,1,2,2,2,1,2,2,2,1,1},此时s数组中值为2的连续区间上的第一个数和第二个数(相同下标的a数组)恰好是具体区间,冲突解决。
具体实现细节看代码。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+;
int n,k,cnt,a[N<<];
int tmp[N<<],s[N<<];
struct seg{
int l,r;
}sgt[N],res[N];
int main(){
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&k)){
cnt=;
for(int i=;i<n;i++){
scanf("%d%d",&sgt[i].l,&sgt[i].r);
a[cnt++]=sgt[i].l,a[cnt++]=sgt[i].l;
a[cnt++]=sgt[i].r,a[cnt++]=sgt[i].r;
}
sort(a,a+cnt);
memset(tmp,,sizeof(tmp));
for(int i=;i<n;i++){
tmp[lower_bound(a,a+cnt,sgt[i].l)-a]++;
tmp[lower_bound(a,a+cnt,sgt[i].r)-a+]--;
}
s[]=tmp[];
for(int i=;i<cnt;i++)
s[i]=s[i-]+tmp[i];
int tot=,flag=;
for(int i=;i<cnt;i++){
if(s[i]>=k){
if(!flag){
res[tot].l=a[i];
flag=;
}
}
else{
if(flag){
flag=;
res[tot++].r=a[i-];
}
}
}
printf("%d\n",tot);
for(int i=;i<tot;i++)
printf("%d %d\n",res[i].l,res[i].r);
}
return ;
}
Codeforces 612D 前缀和处理区间问题的更多相关文章
- codeforces Gym 100187F F - Doomsday 区间覆盖贪心
F. Doomsday Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/F ...
- Codeforces Round #427 (Div. 2) Problem C Star sky (Codeforces 835C) - 前缀和
The Cartesian coordinate system is set in the sky. There you can see n stars, the i-th has coordinat ...
- Educational Codeforces Round 61 F 思维 + 区间dp
https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...
- CSU 1809 - Parenthesis - [前缀和+维护区间最小值][线段树/RMQ]
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1809 Bobo has a balanced parenthesis sequenc ...
- CodeForces 816B 前缀和
To stay woke and attentive during classes, Karen needs some coffee! Karen, a coffee aficionado, want ...
- 洛谷 P1865 A % B Problem[筛素数/前缀和思想/区间质数个数]
题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对于每次询问输出个数 t,如l或r∉[1,m]输出 Cros ...
- Dasha and Photos CodeForces - 761F (前缀优化)
大意: 给定n*m初始字符矩阵, 有k个新矩阵, 第$i$个矩阵是由初始矩阵区间赋值得到的, 求选择一个新矩阵, 使得其余新矩阵到它距离和最小. 字符集比较小, 可以考虑每次区间覆盖对每个字符的贡献. ...
- Codeforces Gym100543L Outer space invaders 区间dp 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543L.html 题目传送门 - CF-Gym100543L 题意 $T$ 组数据. 有 $n ...
- Codeforces 508E Arthur and Brackets 区间dp
Arthur and Brackets 区间dp, dp[ i ][ j ]表示第 i 个括号到第 j 个括号之间的所有括号能不能形成一个合法方案. 然后dp就完事了. #include<bit ...
随机推荐
- CCF201604-1 折点计数 java(100分)
试题编号: 201604-1 试题名称: 折点计数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个整数表示一个商店连续n天的销售量.如果某天之前销售量在增长,而后一天 ...
- Java第九周总结
- python学习,使用requests库来模拟登录github,post请求。
这次我们要模拟登录的页面是 https://github.com/login 首先我们先尝试着登陆一遍分析一下请求, 打开开发者工具下的network选项, 可以很清楚的看到这个会话session,而 ...
- Python随笔day02
算术运算符 + - * ** / // % 比较运算符 > < == >= <= != Python中提供一种更加简单的比较方式. 当判断 ...
- 关于React.PropTypes的废除,以及新版本下的react的验证方式
React.PropTypes是React用来typechecking的一个属性.要在组件的props上运行typechecking,可以分配特殊的propTypes属性: class Greetin ...
- 49. spring boot日志升级篇—理论【从零开始学Spring Boot】
我们之前在其中的一篇文章介绍过如何在spring boot中使用日志记录SLF4J. Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如 ...
- 48. spring boot单元测试restfull API【从零开始学Spring Boot】
回顾并详细说明一下在在之前章节中的中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...
- [luoguP2915] [USACO08NOV]奶牛混合起来Mixed Up Cows(DP)
传送门 f[i][S] 表示当前集合为 S,最后一个数为 i 的最优解 f[i][S] += f[j][S - i] (j, i ∈ S && j != i && ab ...
- noip模拟赛 捡金币
问题描小空正在玩一个叫做捡金币的游戏.游戏在一个被划分成 n行 n列的网格状场地中进行.每一个格子中都放着若干金币,并且金币的数量会随着时间而不断变化. 小空的任务就是在网格中移动,拾取尽量多的金币. ...
- Maven项目pom.xml报错
1.org.apache.maven.archiver.MavenArchiver.getManifest报错 pom.xml第一行报错,如图: 解决办法: 第一步: help ->Instal ...