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

题面

题面较长,略

分析

首先套路的断环为链。对于从l到r的环上区间,若l<=r,我们把它断成两个区间\([l,r],[l+M,r+M]\),否则断成\([l,r+M],[l+M,r+M+M]\)(断成\([l+M,2M]\)也可以)

然后定义从区间[l,r]走到另一个与它相交的区间为1“步”。那么我们可以预处理出区间i走j步能够到达的区间右端点的最大值。注意到区间互不包含,先把区间按左端点为第一关键字,右端点为第二关键字排序。对于区间i,我们找到满足\(l_i<l_j \leq r_i\)的最大\(l_j\),那么\(r_j\)就是走1步能到达的最大区间右端点。因为\(l_j>l_i\),所以\(r_j>r_i\),否则区间j就会被i包含。由于排序过,j显然有单调性,双指针扫一遍就可以了。

	sort(a+1,a+1+sz);
int ptr=1;
for(int i=1;i<=sz;i++){
while(ptr<sz&&a[ptr+1].l<=a[i].r) ptr++;
if(ptr!=i) anc[i][0]=ptr;
}

但是枚举走j步依然是\(O(n^2)\)的,可以用倍增优化。\(anc[i][j]\)表示区间i走j步到达的右端点最大的区间编号。这个可以\(O(n \log n)\)预处理。

查询的时候从i开始跳,一直跳到\(r_{anc[i][j]}\geq l_i+M\)为止,需注意边界条件

int query(int x){
int ans=1;
int r=a[x].l+len; //注意边界,比如3->5,5->1,1->3.必须要跳回原点3,所以是+len而不是+len-1
for(int i=log2n;i>=0;i--){
if(anc[x][i]!=0&&a[anc[x][i]].r<=r){//如果右端点<=i+M,就继续跳
ans+=(1<<i);
x=anc[x][i];
}
}
if(anc[x][0]&&a[x].r<r){//上面求的是右端点<=i+M,可能跳到了<i+M的某一个位置,再跳一步就超过i+M,这种情况也是合法的。特判一下。
ans++;
x=anc[x][0];
}
return ans; //保证一定有解,所以不用判断a[x].r是否>=r
}

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 2000000
#define maxlogn 25
using namespace std;
int n,len;
struct seg{
int l;
int r;
int id;
seg(){ }
seg(int _l,int _r,int _id){
l=_l;
r=_r;
id=_id;
}
friend bool operator < (seg p,seg q){
if(p.l==q.l) return p.r<q.r;
else return p.l<q.l;
}
}a[maxn+5];
int sz;
int log2n;
int ans[maxn+5];
int anc[maxn+5][maxlogn+5]; int query(int x){
int ans=1;
int r=a[x].l+len; //注意边界,比如3->5,5->1,1->3.必须要跳回原点3,所以是+len而不是+len-1
for(int i=log2n;i>=0;i--){
if(anc[x][i]!=0&&a[anc[x][i]].r<=r){
ans+=(1<<i);
x=anc[x][i];
}
}
if(anc[x][0]&&a[x].r<r){
ans++;
x=anc[x][0];
}
return ans;
}
int main(){
int l,r;
scanf("%d %d",&n,&len);
log2n=log2(n*2);
for(int i=1;i<=n;i++){
scanf("%d %d",&l,&r);
if(l<=r){
a[++sz]=seg(l,r,i);
a[++sz]=seg(l+len,r+len,i+n);
}else{
a[++sz]=seg(l,r+len,i);
a[++sz]=seg(l+len,r+len+len,i+n);
}
}
sort(a+1,a+1+sz);
int ptr=1;
for(int i=1;i<=sz;i++){
while(ptr<sz&&a[ptr+1].l<=a[i].r) ptr++;
if(ptr!=i) anc[i][0]=ptr;
}
for(int j=1;j<=log2n;j++){
for(int i=1;i<=sz;i++){
anc[i][j]=anc[anc[i][j-1]][j-1];
}
}
for(int i=1;i<=sz;i++){
if(a[i].id<=n) ans[a[i].id]=query(i);//注意要跳过(l+n,r+n),否则l+len会超过2*len导致答案错误
}
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
}

[BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增)的更多相关文章

  1. 【bzoj4444】[Scoi2015]国旗计划 倍增

    题目描述 给出一个圈和若干段,问:对于所有的 $i$ ,选择第 $i$ 段的情况下,最少需要选择多少段(包括第 $i$ 段)能够覆盖整个圈? 输入 第1行,包含2个正整数N,M,分别表示边防战士数量和 ...

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

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

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

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

  4. [luogu] P4155 [SCOI2015]国旗计划(贪心)

    P4155 [SCOI2015]国旗计划 题目描述 A 国正在开展一项伟大的计划 -- 国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形式共同完成,为此 ...

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

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

  6. 4444: [Scoi2015]国旗计划

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

  7. [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)

    [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...

  8. [bzoj4444] [loj#2007] [洛谷P4155] [Scoi2015] 国旗计划

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

  9. bzoj 4444: [Scoi2015]国旗计划

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

随机推荐

  1. Zabbix4.x安装部署

    zabbix监控的重要性就不用再赘述了.直接上干货. 1.环境背景: Linux:CentOS 7.x, Database:MySQL zabbix server 和 zabbix mysql 安装在 ...

  2. node.js入门学习(五)--Demo模块化改造

    1.node.js中模块的分类 1)node.js内置模块(核心,原生) 所有内置模块在安装node.js时就已经编译成二进制文件,可以直接加载运行(速度较快),部分内置模块,在node.exe这个进 ...

  3. 随堂小测APP使用体验

    随堂小测APP使用体验 先要去注册账号需要填写用户名.密码.手机号.学号/教师号.学校.专业.即可注册,注册成功后,即可登录APP进,登陆进去以后.会有两个界面,课堂和我的,注册.登录简单,通俗易懂, ...

  4. 损坏的RAID5

    损坏的RAID5 string讀入卡cin 関同步 ios::sync_with_stdio(false) 由塊號映射到具體位置 塊號id對應第col個字符串 字符串開始的位置st #include& ...

  5. 在MyEclipse安装Spket插件,用于jQuery代码提示

    Spket插件下载: https://pan.baidu.com/s/1sjz24NF 解压文件,然后将解压后的文件全部复制到MyEclipse安装目录下的dropins包中,重启MyEclipse. ...

  6. CodeChef---- February Challenge 2018----Chef and odd queries(复杂度分块计算)

    链接    https://www.codechef.com/FEB18/problems/CHANOQ/ Chef and odd queries Problem Code: CHANOQ Chef ...

  7. 【Python】学习笔记十二:模块

    模块(module) 在Python中,一个.py文件就是一个模块.通过模块,你可以调用其它文件中的程序 引入模块 先写一个first.py文件,内容如下: def letter(): print(' ...

  8. Python爬取中文页面的时候出现的乱码问题(续)

    我在上一篇博客中说明了在爬取数据的时候,把数据写入到文件的乱码问题 在这一篇里面我做一个总结: 1.首先应该看一个案例 我把数据写在.py文件中: #coding:utf-8 s = 'hehe测试中 ...

  9. java分页原理及分类

    1.使用List接口最终subList()方法实现分页 2.直接使用数据库SQL语句实现分页 3.使用hibernate等框架实现跨数据库的分页 mybatis是面向SQL的,本质上和第二种分页方式相 ...

  10. webrtc相关概念

    SDP Session Description Protocol Session Traversal Utilities for NAT(STUN)Traversal Using Relays aro ...