zoukankan      html  css  js  c++  java
  • [POI2012]RAN-Rendezvous

    2791: [Poi2012]Rendezvous

    Time Limit: 25 Sec  Memory Limit: 128 MB
    Submit: 259  Solved: 160
    [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

    12 5
    4 3 5 5 1 1 12 12 9 9 7 1
    7 2
    8 11
    1 2
    9 10
    10 5

    Sample Output

    2 3
    1 2
    2 2
    0 1
    -1 -1

    HINT

    Source

    [Submit][Status][Discuss]
    
    HOME Back

    题解

    我是很久没有好好写一篇题解了。

    首先分析题意,是要沿着出边跳到相同的节点,说明要求的是lca。

    然后说一下基环树的套路:

    1. 树上倍增可以照常写,注意使用的条件就行了。
    2. 一遍拓扑排序把环找出来,这时候连通且未标记的肯定都在同一个环内。
    3. 以环上任意节点为起点开始做一个环标号,环长度前缀和,还有环总长。具体可以直接用出边跳。
    4. 把不在环上的点的出边反向用来建树,以环为根处理深度,环根标号

    这样询问时的处理套路:

    1. 不在同一连通块内,即环根标号对应节点的环标号不同,那么lca不存在。
    2. 在同一棵树内,即环根标号相同,直接树上lca解决。
    3. 这题我们主要解决的情况——在同一连通块内,但是不在同一棵树内,即环根标号对应节点的环标号相同,但环根标号不同。
      x,y肯定要调到环上,然后分为两种情况,x,y分别跳。用预处理的3解决。

    这样询问时间复杂度可以做到(O(1)),不过这题我的简便写法是(O(log n))的。总时间复杂度(((n+m)log n))

    #include<bits/stdc++.h>
    #define co const
    #define il inline
    #define rg register
    template<class T>T read(){
    	rg T data=0,w=1;rg char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    	for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    	return data*w;
    }
    template<class T>T read(T&x){
    	return x=read<T>();
    }
    typedef long long ll;
    using namespace std;
    typedef pair<int,int> pii;
    #define x first
    #define y second
    
    co int N=5e5+1;
    int n,m,t,f[N][20],deg[N];
    int pos[N],cnt,len[N],s[N];
    int d[N],id[N];
    vector<int> e[N];
    queue<int> q;
    
    int lca(int x,int y){
    	if(d[x]>d[y]) swap(x,y);
    	for(int i=19;i>=0;--i)
    		if(d[f[y][i]]>=d[x]) y=f[y][i];
    	if(x==y) return x;
    	for(int i=19;i>=0;--i)
    		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    pii cmp(co pii&a,co pii&b){
    	if(max(a.x,a.y)<max(b.x,b.y)) return a;
    	if(max(a.x,a.y)>max(b.x,b.y)) return b;
    	if(min(a.x,a.y)<min(b.x,b.y)) return a;
    	if(min(a.x,a.y)>min(b.x,b.y)) return b;
    	return a.x>=a.y?a:b;
    }
    int main(){
    	read(n),read(m);
    	for(int i=1;i<=n;++i) ++deg[read(f[i][0])];
    // prework
    	t=log(n)/log(2);
    	for(int i=1;i<=t;++i)
    		for(int x=1;x<=n;++x) f[x][i]=f[f[x][i-1]][i-1];
    // topsort
    	for(int i=1;i<=n;++i)if(!deg[i]) q.push(i);
    	while(q.size()){
    		int x=q.front();q.pop();
    		if(!--deg[f[x][0]]) q.push(f[x][0]);
    	}
    // circle
    	for(int i=1;i<=n;++i)if(deg[i]&&!pos[i]){
    		++cnt;
    		for(int j=i;!pos[j];j=f[j][0])
    			pos[j]=cnt,s[j]=++len[cnt];
    	}
    // bfs
    	for(int i=1;i<=n;++i){
    		if(pos[i]) id[i]=i,q.push(i);
    		else e[f[i][0]].push_back(i);
    	}
    	while(q.size()){
    		int x=q.front();q.pop();
    		for(unsigned i=0;i<e[x].size();++i){
    			int y=e[x][i];
    			d[y]=d[x]+1,id[y]=id[x];
    			q.push(y);
    		}
    	}
    	while(m--){
    		int x=read<int>(),y=read<int>();
    		if(pos[id[x]]!=pos[id[y]]) puts("-1 -1");
    		else if(id[x]==id[y]){
    			int p=lca(x,y);
    			printf("%d %d
    ",d[x]-d[p],d[y]-d[p]);
    		}
    		else{
    			pii a,b;
    			int sx=s[id[x]],sy=s[id[y]],now=len[pos[id[x]]];
    			a.x=d[x]+(sy-sx+now)%now,a.y=d[y];
    			b.x=d[x],b.y=d[y]+(sx-sy+now)%now;
    			pii ans=cmp(a,b);
    			printf("%d %d
    ",ans.x,ans.y);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    acdream 1017: Fast Transportation 网络流层次图
    centos5的kernel source
    Linux内核源代码的阅读及相关工具介绍(转)
    gcc生成静态库和动态库(转)
    写一篇大家一看就会的教程《JNI初步》(转)
    jni.h
    5分钟学用Lucene
    (VC2005) picture 控件显示16*16的Icon
    (VC/MFC)通过结构体传递参数给线程
    (VC2005)MFC中添加控件的成员变量.
  • 原文地址:https://www.cnblogs.com/autoint/p/11042312.html
Copyright © 2011-2022 走看看