[BZOJ2791][Poi2012]Rendezvous
2791: [Poi2012]Rendezvous
Time Limit: 25 Sec Memory Limit: 128 MB
Submit: 95 Solved: 71
[Submit][Status][Discuss]
Description
给定一个n个顶点的有向图,每个顶点有且仅有一条出边。
对于顶点i,记它的出边为(i, a[i])。
再给出q组询问,每组询问由两个顶点a、b组成,要求输出满足下面条件的x、y:
1. 从顶点a沿着出边走x步和从顶点b沿着出边走y步后到达的顶点相同。
2. 在满足条件1的情况下max(x,y)最小。
3. 在满足条件1和2的情况下min(x,y)最小。
4. 在满足条件1、2和3的情况下x>=y。
如果不存在满足条件1的x、y,输出-1 -1。
Input
第一行两个正整数n和q (n,q<=500,000)。
第二行n个正整数a[1],a[2],...,a[n] (a[i]<=n)。
下面q行,每行两个正整数a,b (a,b<=n),表示一组询问。
Output
输出q行,每行两个整数。
Sample Input
4 3 5 5 1 1 12 12 9 9 7 1
7 2
8 11
1 2
9 10
10 5
Sample Output
1 2
2 2
0 1
-1 -1
HINT
Source
n个点,n条边且每个点都有出边,显然是环套树森林。
先dfs把环套树拆成一堆树,倍增LCA。
先将x,y两个点倍增到环上,然后判断即可。
#include<cstdio>
#include<algorithm>
#define N 500050
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,fa[N][],root,q,circle[N],deep[N];
int num[N],sum[N],tot,pos[N],vis[N];
void findcircle(int x)
{
int now=x;
for(;;x=fa[x][])
{
if(vis[x]==now)break;
if(vis[x])return;
vis[x]=now;
}
tot++;
while(!circle[x])
{
circle[x]=x;
deep[x]=;
num[x]=++sum[tot];
pos[x]=tot;
x=fa[x][];
}
}
void dfs(int x)
{
if(deep[x])return;
dfs(fa[x][]);
circle[x]=circle[fa[x][]];
deep[x]=deep[fa[x][]]+;
for(int i=;(<<i)<deep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
}
inline int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
int t=deep[x]-deep[y];
for(int i=;~i;i--)
if(t&(<<i))x=fa[x][i];
if(x==y)return x;
for(int i=;~i;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
}
bool judge(int a,int b,int c,int d)
{
if(max(a,b)<max(c,d))return ;
if(max(a,b)>max(c,d))return ;
if(min(a,b)<min(c,d))return ;
if(min(a,b)>min(c,d))return ;
if(a>=b)return ;
return ;
}
int main()
{
n=read();q=read();
for(int i=;i<=n;i++)
fa[i][]=read();
for(int i=;i<=n;i++)
findcircle(i);
for(int i=;i<=n;i++)
if(!circle[i])dfs(i);
while(q--)
{
int x=read(),y=read();
if(pos[circle[x]]!=pos[circle[y]])
{
puts("-1 -1");
continue;
}
if(circle[x]==circle[y])
{
int t=lca(x,y);
printf("%d %d\n",deep[x]-deep[t],deep[y]-deep[t]);
continue;
}
int ans1=deep[x]-,ans2=deep[y]-,t=pos[circle[x]];
x=num[circle[x]];y=num[circle[y]];
int z1=(sum[t]+y-x)%sum[t],z2=sum[t]-z1;
if(judge(ans1+z1,ans2,ans1,ans2+z2))
printf("%d %d\n",ans1+z1,ans2);
else printf("%d %d\n",ans1,ans2+z2);
}
}
[BZOJ2791][Poi2012]Rendezvous的更多相关文章
- [BZOJ2791]:[Poi2012]Rendezvous(塔尖+倍增LCA)
题目传送门 题目描述 给定一个有n个顶点的有向图,每个顶点有且仅有一条出边.每次询问给出两个顶点${a}_{i}$和${b}_{i}$,求满足以下条件的${x}_{i}$和${y}_{i}$: ...
- 【BZOJ2791】[Poi2012]Rendezvous 倍增
[BZOJ2791][Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组 ...
- 【BZOJ 2791】 2791: [Poi2012]Rendezvous (环套树、树链剖分LCA)
2791: [Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组询问由两 ...
- bzoj 2791 [Poi2012]Rendezvous 基环森林
题目大意 给定一个n个顶点的有向图,每个顶点有且仅有一条出边. 对于顶点i,记它的出边为(i, a[i]). 再给出q组询问,每组询问由两个顶点a.b组成,要求输出满足下面条件的x.y: 从顶点a沿着 ...
- [Poi2012]Rendezvous
题目描述 给定一个n个顶点的有向图,每个顶点有且仅有一条出边. 对于顶点i,记它的出边为(i, a[i]). 再给出q组询问,每组询问由两个顶点a.b组成,要求输出满足下面条件的x.y: 从顶点a沿着 ...
- POI2012题解
POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...
- LG3533 [POI2012]RAN-Rendezvous
2791: [Poi2012]Rendezvous Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 259 Solved: 160[Submit][S ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 「POI2012」约会 Rendezvous
#2691. 「POI2012」约会 Rendezvous 这题我简直不想说什么了,什么素质,卡常数…… “每个顶点有且仅有一条出边”,所以是一道基环树的题,首先tarjan缩点,在缩完点后的图上求a ...
随机推荐
- 【PHP&&FileIO】
在程序员的眼中,文件不应当仅仅是一部电影.一首歌曲.一个pdf文件,它应该被视为一个文件夹,而我们所熟知的文件,应当是它的特例. 在web开发中,文件的上传和下载是文件变成的一个实际应用. 延续cru ...
- mysql 如何设置自动增长序列 sequence(一)
背景:由于项目需要,必须用mysql设置主键自增长,而且想用字符串的.经过上网查找并且实验,终于做出了一套方案.现在就共享给大家! 解决思路:由于mysql不带sequence,所以要手写的,创建一张 ...
- OCJP(1Z0-851) 模拟题分析(四)over
Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...
- SSAS Cube 维度成员关系Rigid 和 Flexible
维度成员关系指示成员关系是否随时间而更改. 值为 Rigid 和 Flexible,前者表示成员之间的关系不随时间而更改,后者表示成员之间的关系随时间而更改. 默认值为 Flexible. 指定适 ...
- “init terminating in do_boot” Windows10 Rabbit MQ fails to start
在Windows 10环境下安装rabbitmq-server-3.6.2后,CMD中运行命令:rabbitmq-plugins enable rabbitmq_management 报错: { , ...
- Web开发基本准则-55实录-Web访问安全
Web开发工程师请阅读下面的前端开发准则,这是第一部分,强调了过去几年里我们注意到的Web工程师务须处理的Web访问安全基础点.尤其是一些从传统软件开发转入互联网开发的工程师,请仔细阅读,不要因为忽视 ...
- Sublime Text3 配置Node.js运行命令
在Sublime Text中可以很容易配置新的编译运行命令,下面的截图是汉化版的中文菜单,英文菜单请直接对照. 首先需要在本地安装Node,默认的Node会加入到系统的环境变量,这样执行Node命 ...
- 多进程程序设计,王明学learn
多进程程序设计 一.函数学习 1.1 创建进程fork 1.1.1 函数原形 pid_t fork(void); 1.1.2 函数功能 创建一个子进程 1.1.3 所属头文件 <unistd.h ...
- 在Salesforce中创建Schedule的Job去定时触发对应的Class
在Salesforce中也存在着Job的概念,当然了我们可以创建Schedule的Job去定时触发对应的Class,来完成我们所需要定时处理的功能,比如:定时同步数据. 具体处理步骤如下所示: 1): ...
- java杂记——数组拷贝
这里介绍两种java提供的数组拷贝方法: (1)Arrays提供的copyOf(T src, T desLength)和copyOfRange(T src, int from, int to) (2) ...