zoukankan      html  css  js  c++  java
  • #圆方树,树链剖分#P4334 [COI2007] Policija

    题目


    分析

    先建一棵圆方树,必经点(z)就是满足(z)(x)(y)之间的路径上,
    这个直接用树链剖分做,必经边必须要满足不在环上,
    那么这个必经边就可以找到一个方点,就可以转换成必经点的问题


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #define rr register
    using namespace std;
    const int N=200011; struct node{int y,next;}e[N*5],E[N*5]; map<pair<int,int>,int>uk;
    int dfn[N],low[N],stac[N],hs[N],dep[N],nfd[N],fat[N],big[N],et=1,Et=1;
    int as[N],siz[N],Top[N],cnt[N],dis[N],tot,TOP,n,ext,m,las,a[N],Q;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void add(int x,int y){
    	e[++et]=(node){y,as[x]},as[x]=et;
    	e[++et]=(node){x,as[y]},as[y]=et;
    }
    inline signed min(int a,int b){return a<b?a:b;}
    inline void tarjan(int x,int F){
    	dfn[x]=low[x]=++tot,stac[++TOP]=x;
    	for (rr int i=hs[x];i;i=E[i].next)
    	if (!dfn[E[i].y]){
    		tarjan(E[i].y,i^1);
    		low[x]=min(low[x],low[E[i].y]);
    		if (dfn[x]<=low[E[i].y]){
    			cnt[++ext]=2;
    			if (dfn[x]<low[E[i].y]){
    				rr int X=x,Y=E[i].y;
    				if (X>Y) X^=Y,Y^=X,X^=Y;
    				uk[make_pair(X,Y)]=ext; 
    			}
    			for (;stac[TOP]!=E[i].y;--TOP)
    			    add(ext,stac[TOP]),++cnt[ext];
    			add(ext,stac[TOP--]),add(ext,x);
    		}
    	}else if (i!=F) low[x]=min(low[x],dfn[E[i].y]);
    }
    inline void dfs1(int x,int fa){
    	dep[x]=dep[fa]+1,fat[x]=fa,
    	dis[x]=dis[fa]+(x<=n),siz[x]=1;
    	for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
    	if (e[i].y!=fa){
    		dfs1(e[i].y,x),siz[x]+=siz[e[i].y];
    		if (siz[e[i].y]>SIZ) big[x]=e[i].y,SIZ=siz[e[i].y];
    	}
    }
    inline void dfs2(int x,int linp){
    	dfn[x]=++tot,nfd[tot]=x,Top[x]=linp;
    	if (!big[x]) return; dfs2(big[x],linp);
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fat[x]&&e[i].y!=big[x])
    	    dfs2(e[i].y,e[i].y);
    }
    inline bool pass_by(int x,int y,int z){
    	for (;Top[x]!=Top[y];x=fat[Top[x]]){
    		if (dep[Top[x]]<dep[Top[y]]) x^=y,y^=x,x^=y;
    		if (Top[z]==Top[x]&&dep[z]<=dep[x]) return 1;
    	}
    	if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
    	if (Top[y]==Top[z]&&dep[x]<=dep[z]&&dep[z]<=dep[y]) return 1;
    	return 0;
    }
    signed main(){
    	ext=n=iut(),m=iut();
    	for (rr int i=1;i<=m;++i){
    		rr int x=iut(),y=iut();
    		E[++Et]=(node){y,hs[x]},hs[x]=Et,
    		E[++Et]=(node){x,hs[y]},hs[y]=Et;
    	}
    	tarjan(1,0),tot=TOP=0,dfs1(1,0),dfs2(1,1);
    	for (rr int Q=iut();Q;--Q){
    		rr int opt=iut(),x=iut(),y=iut(),z;
    		if (opt==1){
    			rr int X=iut(),Y=iut();
    			if (X>Y) X^=Y,Y^=X,X^=Y;
    			z=uk[make_pair(X,Y)];
    			if (!z) {puts("yes"); continue;}
    		}else z=iut();
    		puts(pass_by(x,y,z)?"no":"yes");
    	}
    	return 0;
    }
    
  • 相关阅读:
    需求征集系统第四天
    EL表达式和JSTL
    需求征集系统第三天
    [2019.1.6]BZOJ4197 [Noi2015]寿司晚宴
    [2019.1.7]BZOJ1011 [HNOI2008]遥远的行星
    [2019.1.3]BZOJ4326 NOIP2015 运输计划
    [2019.1.2]BZOJ2115 [Wc2011] Xor
    [2019.1.2]BZOJ2460 [BeiJing2011]元素
    [2019.1.1]BZOJ1806 [Ioi2007]Miners 矿工配餐
    [2019.1.1]BZOJ4195 [Noi2015]程序自动分析
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14980367.html
Copyright © 2011-2022 走看看