CF1515G Phoenix and Odometers 题解

Codeforces
Luogu

Description.

给定一张有向图,\(q\) 次询问,每次询问是否存在一个经过 \(v\) 的环,满足路径长 \(\equiv s\pmod t\)

Solution.

奶到 \(\gcd\) 了,可能再想一步就想通了,但是停下了,有点可惜。

考虑一个环肯定存在于一个强连通分量里,而每个强连通分量都可以构造一个环经过所有点,所以每个强连通分量答案都一样。
所以首先 tarjan 缩点,然后对每个强连通分量求答案。

对于每个强连通分量,很显然能否就与它所有环 \(\gcd\) 的答案有关了,设这个东西是 \(w\)
设路径长为 \(l\),那如果 \(l\bmod\gcd(s,w)\) 不为 \(0\),必然不行,否则根据裴蜀定理一定可行。
然后我们只需要统计所有环的 \(\gcd\) 就行了。
直接搞一个 \(\text{dfs}\) 序,然后对于每条非树边加入成环大小即可。
证明略,感性理解一下发现是对的,证明详见洛谷题解区。

Coding.

点击查看不好看代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
    x=0;char c=getchar(),f=0;
    for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}/*}}}*/
const int N=200005;struct edge{int to,w,nxt;}e[N];int n,m,q,et,head[N];
inline void adde(int x,int y,int w) {e[++et]=(edge){y,w,head[x]},head[x]=et;}
int dt,dfn[N],low[N],cl[N],st[N],tp,ct;ll ds[N],gd[N];char tv[N],vs[N];
inline void tarjan(int x)
{
	dfn[x]=low[x]=++dt,st[++tp]=x,tv[x]=1;
	for(int i=head[x];i;i=e[i].nxt)
		if(!dfn[e[i].to]) tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
		else if(tv[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);
	if(low[x]==dfn[x]) {int y=++ct;do tv[y=st[tp--]]=0,cl[y]=ct;while(y^x);}
}
inline void dfs(int x,int col)
{
	vs[x]=1;for(int i=head[x];i;i=e[i].nxt) if(cl[e[i].to]==col)
	{
		if(!vs[e[i].to]) ds[e[i].to]=ds[x]+e[i].w,dfs(e[i].to,col);
		else gd[col]=__gcd(gd[col],ds[x]+e[i].w-ds[e[i].to]);
	}
}
int main()
{
	read(n,m);for(int i=1,x,y,w;i<=m;i++) read(x,y,w),adde(x,y,w);
	for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
	for(int i=1;i<=n;i++) if(!vs[i]) dfs(i,cl[i]);
	//for(int i=1;i<=n;i++) printf("%d%c",cl[i],i==n?'\n':' ');
	//for(int i=1;i<=ct;i++) printf("%lld%c",gd[i],i==ct?'\n':' ');
	int Ca,v;read(Ca);for(ll s,t;Ca--;) read(v,s,t),puts(s%__gcd(t,gd[cl[v]])?"NO":"YES");
	return 0;
}
原文地址:https://www.cnblogs.com/pealfrog/p/15216584.html