zoukankan      html  css  js  c++  java
  • #Tarjan#洛谷 5676 [GZOI2017]小z玩游戏

    题目


    分析

    可能玩两次也就是形成环即是Tarjan缩点后在同一个强连通分量
    如果按照游戏连边数量将达到(O(n^2)),当中其实有很多边可以共用,
    考虑(i)连向(i)的倍数,以及有趣程度连接兴奋程度,其实连接倍数可以优化一下,
    比如说(i)连向(j)(j)连向(k),那么(i)连向(k)的边完全可以被省掉,
    那么对于每个数连接其与一个质数的乘积,根据埃氏筛建的边应该为(O(nloglogn))
    实际上仍然达不到上界,总边数在(4n)以内


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #define rr register
    using namespace std;
    const int M=100000,N=M|15; struct node{int y,next;}e[N<<2];
    int dfn[N],stac[N],low[N],et,eT,v[N],St[N],Ed[N],ans;
    int Cnt,col[N],Top,as[N],prime[N],bs[N],n,tot,cnt;
    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 signed min(int a,int b){return a<b?a:b;}
    inline void add(int x,int y){e[++et]=(node){y,as[x]},as[x]=et;}
    inline void tarjan(int x){
    	dfn[x]=low[x]=++tot,stac[++Top]=x,v[x]=1;
    	for (rr int i=as[x];i;i=e[i].next)
    	if (!dfn[e[i].y]){
    		tarjan(e[i].y);
    		low[x]=min(low[x],low[e[i].y]);
    	}else if (v[e[i].y])
    	    low[x]=min(low[x],dfn[e[i].y]);
    	if (dfn[x]==low[x]){
    		rr int y; ++cnt;
    		do{
    			y=stac[Top--];
    			col[y]=cnt,v[y]=0;
    		}while (y!=x);
    	}
    }
    signed main(){
    	for (rr int i=2;i<=M;++i){
    		if (!v[i]) prime[++Cnt]=i;
    		for (rr int j=1;j<=Cnt&&prime[j]<=M/i;++j){
    			v[i*prime[j]]=1;
    			if (i%prime[j]==0) break;
    		}
    	}
    	for (rr int i=1;i<=M;++i)
    	for (rr int j=1;j<=Cnt&&prime[j]<=M/i;++j)
    	    add(i,i*prime[j]);
    	memcpy(bs,as,sizeof(as)),eT=et;
    	for (rr int T=iut();T;--T){
    		memcpy(as,bs,sizeof(bs)),et=eT;
    		memset(dfn,0,sizeof(dfn));
    		memset(v,0,sizeof(v));
    		memset(col,0,sizeof(col));
    		memset(low,0,sizeof(low));
    		n=iut(),ans=tot=0;
    		for (rr int i=1;i<=n;++i) St[i]=iut();
    		for (rr int i=1;i<=n;++i) Ed[i]=iut();
    		for (rr int i=1;i<=n;++i) add(St[i],Ed[i]);
    		tarjan(1);
    		for (rr int i=1;i<=n;++i)
    		if (col[St[i]]==col[Ed[i]]) ++ans;
    		print(ans),putchar(10);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    TTVNC 2.0 发布了
    软件收费问题,目前没有限制, 全部免费
    为什么服务器端要确认才能连接通过
    关于transfer file功能的使用?
    同一台机器上测试会出现很多黑块
    TTVNC 设计理念
    TTVNC 2.2发布
    redis连接池 jedis2.9.0.jar+commonspool22.4.2.jar
    Calendar add 方法 和set方法
    jar包读取包内properties文件
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14488619.html
Copyright © 2011-2022 走看看