原题来自与:洛谷 P5676(GZOI2017)  链接: https://www.luogu.com.cn/problem/P5676

题面:

题意比较明显,如果已经建好了边,那么跑个Tarjan 就完了。

但是问题在于建边的复杂度,比较好想的是n 的建边方式。

但是时间肯定不允许。

那么我们就要想一种时间复杂度较小的建边方式。

可以考虑引入中间变量兴奋程度

那么如何建边,

首先将点开多一些

把中间变量兴奋程度也当作点

然后建边

1.建一个由 有趣程度 到 点 的边

2.建一个由 点 到 兴奋程度 的边

3.重点:建一个兴奋程度整数倍的边。

然后就跑一边tarjan就完了,

下面是代码(加注释):

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=500005*4;
int n;
int Max=0;
struct edge{
int to,next;
}e[maxn];int head[maxn],cnt=0;
void add(int x,int y){
e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;
}
int w[maxn],b[maxn];
int dfn[maxn],low[maxn],dfs_clock,sta[maxn],top,belong[maxn],siz[maxn],vis[maxn],dcc;
void dfs(int u){
dfn[u]=low[u]=++dfs_clock;
sta[++top]=u;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!belong[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){//特殊的出栈方式
dcc++;
belong[u]=dcc;
siz[dcc]++;
while(sta[top]!=u){
int x=sta[top--];
belong[x]=dcc;
siz[dcc]++;
vis[x]=1;
}
if(siz[dcc]>1)vis[u]=1;
top--;
}
}
void clear(){
memset(e,0,sizeof(e));
memset(head,0,sizeof(head));
cnt=0;Max=0;
memset(w,0,sizeof(w));
memset(b,0,sizeof(b));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
dfs_clock=0;
memset(sta,0,sizeof(siz));
top=0;
memset(belong,0,sizeof(belong));
memset(siz,0,sizeof(siz));
memset(vis,0,sizeof(vis));
dcc=0;
}
int main(){
//freopen("a.in","r",stdin);
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
add(n+w[i],i);
Max=max(Max,w[i]);//建第一种边
}
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
add(i,n+b[i]);//见第二种边
}
for(int i=1;i<=Max;i++){
for(int j=2;j*i<=Max;j++){//第三种边
add(i+n,j*i+n);
}
}
if(n==1){//数据特判,详见样例1
printf("1\n");clear();continue;
} for(int i=1;i<=n;i++){//tarjan
if(!dfn[i])dfs(i);
}
int ans=0;
for(int i=1;i<=n;i++){//判断答案,注意只要1——n的点
if(vis[i])ans++;
}
printf("%d\n",ans);
clear();
}
return 0;
}

希望大家能学会这种神奇的建边方式

最新文章

  1. 控制TextField的内容长度
  2. 你不知道的Javascript(上卷)读书笔记之一 ---- 作用域
  3. ArrayList如何实现线程安全
  4. 安装docker-compose
  5. SuperSocket 1.6.4 通过FixedHeaderReceiveFilter解析自定义协议
  6. require.js的用法
  7. 数据访问层DAL(数据库访问抽象类DataProvider)
  8. ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况
  9. Oracle监控指标
  10. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)
  11. CNCC2017梳理
  12. JAVA工程师面试题【来自并发编程网】
  13. Hper-V卸载
  14. 【笔记】Python基础一 :变量,控制结构,运算符及数据类型之数字,字符串,列表,元组,字典
  15. 48-Python 安装pyautogui失败解决办法
  16. 用C++的 new 代替 C 的 malloc 进行内存分配
  17. libgdx学习记录16——资源加载器AssetManager
  18. Aheadof Time Compilation(AOT) vs (JIT)Just In Time compilation approach
  19. PHP数组合并:[“+”运算符]、[array_merge]、[array_merge_recursive]区别
  20. MyBatis(1)优点&amp;介绍&amp;工程

热门文章

  1. 去摆摊吧,落魄的Java程序员
  2. 因为 MongoDB 没入门,我丢了一份实习工作
  3. MySQL 8.0 yum安装和配置
  4. SignalR控制台自托管服务端向web客户端指定用户推送数据,客户端断线重连
  5. Hadoop + Hive + HBase + Kylin伪分布式安装
  6. java中工厂模式
  7. 2.K8S的核心资源管理方法
  8. 磨皮美颜算法 附完整C代码
  9. vue 深度拷贝 除去空的参数
  10. js清除所有的空格