• luogu P5676 [GZOI2017]小z玩游戏 |Tarjan+技巧优化建图


    题目描述

    小 z 很无聊。

    小 z 要玩游戏。

    小 z 有NNN个新游戏,第iii个游戏看上去的有趣程度为wiw_iwi​。

    小 z 很挑,他只会玩看上去的有趣程度是自己兴奋程度整数倍的游戏。

    由于游戏实际上有好玩的也有不好玩的,玩完第iii个游戏后,小 z 的兴奋程度会变为eie_iei​。

    已知小 z 初始兴奋程度为111,请问小 z 有多少个游戏可能会玩两次?
    输入格式

    第一行一个正整数TTT,表示测试数据组数,最多101010组。

    对于每组测试数据:

    第一行一个正整数NNN,表示游戏的个数。
    第二行NNN个正整数,第iii个数wiw_iwi​,表示第iii个游戏看上去的有趣程度为wiw_iwi​。
    第三行NNN个正整数,第iii个数eie_iei​,表示小 z 玩完第iii个游戏后,小 z 的兴奋程度会变为eie_iei​。
    

    输出格式

    共TTT行。

    每行一个正整数,表示对应测试数据,小 z 可能会玩两次的游戏数量。


    一个数组初始化问题,改了我一天..

    建虚点,模拟找倍数过程

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=2e5+1,M=80*N;
    int nxt[M],head[N],go[M],tot;
    inline void add(int u,int v){
    	nxt[++tot]=head[u];head[u]=tot;go[tot]=v;
    }
    int n;
    bool vis[N];
    int dfn[N],low[N],co[N],st[N],top,col,num;
    inline void clear(){
    	memset(head,0,sizeof(head));
    	memset(vis,0,sizeof(vis));
    	memset(nxt,0,sizeof(nxt));
    	memset(dfn,0,sizeof(dfn));
    	memset(low,0,sizeof(low));
    	memset(co,0,sizeof(co));
    	col=0; num=0; tot=0;
    }
    void Tarjan(int u){
    	st[++top]=u;
    	dfn[u]=low[u]=++num;
    	for(int i=head[u];i;i=nxt[i]){
    		int v=go[i];
    		if(!dfn[v]){
    			Tarjan(v); 
    			low[u]=min(low[u],low[v]);
    		}else if(!co[v]) 
    		low[u]=min(low[u],dfn[v]);
    	}
    	if(dfn[u]==low[u]){
    		co[u]=++col;
    		int siz=1;
    		while(st[top]!=u){
    			co[st[top]]=col;
    			vis[st[top]]=1;
    			siz++;
    			top--;
    		}
    		if(siz>1)vis[u]=1;
    		--top;
    	}
    }
    signed main(){
    	int T; cin>>T;
    	while(T--){
    		scanf("%d",&n);  
    		int Max=0;
    		for(int i=1,x;i<=n;i++)scanf("%d",&x),add(n+x,i),Max=max(Max,x);
    		for(int i=1,x;i<=n;i++)scanf("%d",&x),add(i,n+x);
    		for(int i=1;i<=Max;i++)for(int j=2;j*i<=Max;j++)
    			add(n+i,n+i*j);
    		
    		for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i);
    		
    		int ans=0;
    		for(int i=1;i<=n;i++)if(vis[i])ans++;
    
    		printf("%d
    ",ans);
    		clear();
    	}
    }
    
  • 相关阅读:
    你是一直认为 count(1) 比 count(*) 效率高么?
    秒杀系统是如何防止超卖的?
    百亿流量微服务网关的设计与实现
    中台
    Token 、Cookie、Session
    HyperLedger Fabric 1.4 区块链应用场景(3.1)
    HyperLedger Fabric 1.4 区块链工作过程(2.3)
    HyperLedger Fabric 1.4 区块链技术原理(2.2)
    HyperLedger Fabric 1.4 区块链技术定义(2.1)
    HyperLedger Fabric 1.4 区块链技术发展(1.3)
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12669604.html
Copyright © 2020-2023  润新知