CF1867D Cyclic Operations
事实上我们可以发现,如果\(b_i=x\)最后,那么我们可以连一条边,从\(i\)到\(x\)
这样我们就得到了一个有向图,在这张有向图呢,可以证明的是
如果\(k=1\),那么必须全部都是自环。
若不成立,则必须每个环的大小恰好为\(k\)
这样就可以解决了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
using namespace std;
int t;
int to[200005];
int ff;
int n,k;
int b[200005];
int du[200005];
int vis[200005];
queue<int> q;
void dfs(int now,int f,int l){
if(to[now]==f){
du[to[now]]--;
if(l!=k) ff=0;
return ;
}
du[to[now]]--;
dfs(to[now],f,l+1);
return ;
}
void print(){
printf("%s\n",(ff==1?"Yes":"No"));
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i){
scanf("%d",&b[i]);
}
ff=1;
if(k==1){
ff=1;
for(int i=1;i<=n;++i){
if(b[i]!=i) ff=0;
}
print();
}else{
memset(du,0,sizeof(du));
for(int i=1;i<=n;++i){
to[i]=b[i];
du[b[i]]++;
}
while(!q.empty()) q.pop();
for(int i=1;i<=n;++i){
if(du[i]==0) q.push(i);
}
while(!q.empty()){
int x=q.front();
q.pop();
du[to[x]]--;
if(du[to[x]]==0) q.push(to[x]);
}
for(int i=1;i<=n;++i){
if(du[i]!=0){
dfs(i,i,1);
if(!ff) break;
}
}
print();
}
}
return 0;
}