zoukankan      html  css  js  c++  java
  • 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();
    	}
    }
    
  • 相关阅读:
    判断qq浏览器和uc浏览器?
    做前端能避免的错误总结
    css布局
    border-radius后面写px/rem与百分比有什么区别?
    vertical-align
    localstorage和cookie的设置方法和获取方法
    怎么让列表的文字只显示两行,多出的出现省略号?
    avalon在公共页面里面写的功能,怎么让某些页面不引用到这个方法和html?
    小程序
    webpack
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12669604.html
Copyright © 2011-2022 走看看