#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;
} 
posted @ 2021-03-05 21:37  lemondinosaur  阅读(104)  评论(0编辑  收藏  举报