题目描述

给出一个圈和若干段,问:对于所有的 $i$ ,选择第 $i$ 段的情况下,最少需要选择多少段(包括第 $i$ 段)能够覆盖整个圈?

输入

第1行,包含2个正整数N,M,分别表示边防战士数量和边防站数量。
随后n行,每行包含2个正整数。其中第i行包含的两个正整数Ci、Di分别表示i号边防战士常驻的两个边防站编号,
Ci号边防站沿顺时针方向至Di号边防站力他的奔袭区间。数据保证整个边境线都是可被覆盖的。

输出

输出数据仅1行,需要包含n个正整数。其中,第j个正整数表示j号边防战士必须参加的前提下至少需要
多少名边防战士才能顺利地完成国旗计划

样例输入

4 8
2 5
4 7
6 1
7 3

样例输出

3 3 4 3


题解

倍增

如果将选择的区间按照右端点正方向顺序考虑的话,那么如果选择了某个区间,下一个区间的选择一定是所有左端点小于等于该区间右端点中,右端点最靠后的那一个。

因此首先断环成链,然后选择区间 $[l,r]$ 后,下一个选择就应该是左端点在 $[1,r]$ 范围内,右端点最靠后的。

所以对于每一个区间 $[l,r]$ ,在 $l$ 位置上加入 $r$ ,然后求前缀最大值即可得到每个位置选上一个区间后最远能够覆盖到哪。

我们要求的是覆盖整个圈,因此可以考虑倍增算法,预处理出 $f[i][j]$ 表示从 $j$ 位置选择 $2^i$ 段区间最远能够覆盖到哪。那么上面的全椎最大值就是 $f[0][j]$ 。

根据递推式 $f[i][j]=f[i-1][f[i-1][j]]$ 预处理出 $f$ 数组,然后倍增求解。从大到小枚举 $i$ ,如果加入一段不能覆盖整个圈则加入,否则不加入。最后加上2(本身+无限逼近后剩余的一段)即为答案。

注意一下区间跨越 $m$ 的处理 ,详见代码。

时间复杂度 $O(n\log n)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
#define pos(x) lower_bound(v + 1 , v + m + 1 , x) - v
using namespace std;
int a[N] , b[N] , v[N << 1] , f[20][N << 2];
int main()
{
int n , m = 0 , i , j , t , ans;
scanf("%d%*d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &a[i] , &b[i]) , v[++m] = a[i] , v[++m] = b[i];
sort(v + 1 , v + m + 1);
for(i = 1 ; i <= n ; i ++ )
{
a[i] = pos(a[i]) , b[i] = pos(b[i]);
if(a[i] < b[i])
{
f[0][a[i]] = max(f[0][a[i]] , b[i]);
f[0][a[i] + m] = max(f[0][a[i] + m] , b[i] + m);
}
else
{
f[0][1] = max(f[0][1] , b[i]);
f[0][a[i]] = max(f[0][a[i]] , b[i] + m);
f[0][a[i] + m] = max(f[0][a[i] + m] , m << 1);
}
}
for(i = 1 ; i <= m << 1 ; i ++ ) f[0][i] = max(f[0][i] , f[0][i - 1]);
for(t = 1 ; (1 << t) <= m << 1 ; t ++ )
for(i = 1 ; i <= m << 1 ; i ++ )
f[t][i] = f[t - 1][f[t - 1][i]];
for(i = 1 ; i <= n ; i ++ )
{
ans = 0;
if(a[i] < b[i]) a[i] += m;
for(j = t - 1 ; ~j ; j -- )
if(f[j][b[i]] < a[i])
ans += (1 << j) , b[i] = f[j][b[i]];
printf("%d" , ans + 2);
if(i < n) printf(" ");
}
return 0;
}

【bzoj4444】[Scoi2015]国旗计划 倍增的更多相关文章

  1. [BZOJ4444][SCOI2015]国旗计划(倍增)

    链上是经典贪心问题,将线段全按左端点排序后把点全撒在线段右端点上.这里放到环上,倍长即可. 题目保证不存在区间包含情况,于是有一种暴力做法,先将战士的管辖区间按左端点从小到大排序,对于询问x,从x战士 ...

  2. [BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增)

    [BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增) 题面 题面较长,略 分析 首先套路的断环为链.对于从l到r的环上区间,若l<=r,我们 ...

  3. BZOJ4444 SCOI2015国旗计划(贪心+倍增)

    链上问题是一个经典的贪心.于是考虑破环成链,将链倍长.求出每个线段右边能作为后继的最远线段,然后倍增即可. #include<iostream> #include<cstdio> ...

  4. 2019.03.26 bzoj4444: [Scoi2015]国旗计划(线段树+倍增)

    传送门 题意简述:现在给你一个长度为mmm的环,有nnn条互不包含的线段,问如果强制选第iii条线段至少需要用几条线段覆盖这个环,注意用来的覆盖的线段应该相交,即[1,3],[4,5][1,3],[4 ...

  5. BZOJ4444 : [Scoi2015]国旗计划

    首先将坐标离散化,因为区间互不包含,可以理解为对于每个起点输出最少需要多少个战士. 将环倍长,破环成链,设$f[i]$表示区间左端点不超过$i$时右端点的最大值,可以通过$O(n)$递推求出. 那么如 ...

  6. [BZOJ4444][SCOI2015]国旗计划-[ST表]

    Description 传送门 Solution 说真的这道题在场上没做出来的我必定是脑子有洞.. 我们用st表记录以某个位置开始,派了1<<j个战士能到达的最远位置. 由于边境线是一圈, ...

  7. 【BZOJ4444】[Scoi2015]国旗计划 双指针+倍增

    [BZOJ4444][Scoi2015]国旗计划 Description A国正在开展一项伟大的计划——国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形 ...

  8. [SCOI2015]国旗计划[Wf2014]Surveillance

    [SCOI2015]国旗计划 A国正在开展一项伟大的计划——国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这 项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了N名 ...

  9. 4444: [Scoi2015]国旗计划

    4444: [Scoi2015]国旗计划 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 485  Solved: 232 Description A国 ...

随机推荐

  1. javascript array.property.slice.call

    function foo() { //var var1=Array.prototype.slice.call(arguments); var var1=[].slice.call(arguments) ...

  2. 《Java I/O 从0到1》 - 第Ⅰ滴血 File

    前言 File 类的介绍主要会依据<Java 编程思想>以及官网API .相信大家在日常工作中,肯定会遇到文件流的读取等操作,但是在搜索过程中,并没有找到一个介绍的很简洁明了的文章.因此, ...

  3. stm32中如何进行printf重定向用于串口调试输出

    1 在main中包含stdio.h 文件 2 Target选项框里选Use MicroLib 选项 3 在main中添加UART1_Configuration()初始化的代码 Uart1初始化,voi ...

  4. JAVA日志框架概述

            日志用来记录应用的运行状态以及一些关键业务信息,其重要性不言而喻,通常我们借助于现有的日志框架完成日志输出.目前开源的日志框架很多,常见的有log4j.logback等,有时候我们还会 ...

  5. Python Road

    引子 雁离群兮不知所归,路遥远兮吾将何往   Python Road[第一篇]:Python简介 Python Road[第二篇]:Python基本数据类型 Python Road[第三篇]:Pyth ...

  6. 汽车VIN码,车架号,移动端,服务器端OCR识别 技术公司

    很多人在购买车辆的时候,只关注性能.外观.内饰等,其实真正的内行是首先看车辆的VIN码,也叫车架号码. VIN码(车架号码)是一辆车的唯一身份证明,一般在车辆的挡风玻璃处,有的在车辆防火墙上,或B柱铭 ...

  7. 爬虫——URL模块爬取糗事百科段子

    最简单的爬取网页找有用信息,难点应该是正则锁定有用信息部分,看了一些其他大神的正则,最后还是决定按照自己理解写一个,果然我头脑相对简单,写出来的粗糙而易理解,也完成了自己想要的需求,就这样了~ # - ...

  8. Shader Forge学习

    最近学习了一下shader forge,一个屌屌哒插件用来生成shader.尽管其降低了制作shader的难度,但是真的想做出满意的shader的话还是得有一定的shader基础.但是仅仅是做出一些简 ...

  9. Unity Android设备的输入

    Unity Android设备的输入 1依据屏幕位置输入 有的时候也许是为了整个有些风格的干净,减少屏幕上的UI图标,以至于摒弃了虚拟按键这种常用的输入方式.为了替代虚拟按键的输入方式而选择了依据点击 ...

  10. Vue 编程之路(三)—— Vue 中子组件在父组件的 v-for 循环里,父组件如何调取子组件的事件

    (标题的解决方案在第二部分) 最近公司的一个项目中使用 Vue 2.0 + element UI 实现一个后台管理系统的前端部分,属于商城类型. 一.前期思路: 其中在“所有订单”页面,UI 给的设计 ...