思路:
x−>f(x)建图,看每个环的平均值是否相同。
代码:
const int maxn=2e5+7,maxm=2e5+7; ll n; ll h[maxn],e[maxm],ne[maxm],idx,f[maxn],w[maxn]; ll dfn[maxn],low[maxn],timetamp,belong[maxn]; stack<int>stk; bool st[maxn]; ll scc_cnt; void init(){ memset(h,-1,sizeof h); memset(w,0,sizeof w); memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(belong,0,sizeof belong); memset(st,0,sizeof st); idx=scc_cnt=timetamp=0; } void add(ll a,ll b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void tarjan(int u){ dfn[u]=low[u]=++timetamp; stk.push(u);st[u]=1; for(int i=h[u];~i;i=ne[i]){ int j=e[i]; if(!dfn[j]){ tarjan(j); low[u]=min(low[u],low[j]); } else if(st[j]) low[u]=min(low[u],dfn[j]); } if(dfn[u]==low[u]){ ++scc_cnt; int y; do{ y=stk.top(); stk.pop(); belong[y]=scc_cnt; st[y]=0; }while(y!=u); } } vector<int>g[maxn]; int main(){ int _=read; while(_--){ init(); n=read; rep(i,1,n){ f[i]=read; add(i,f[i]); g[i].clear(); } rep(i,1,n) if(!dfn[i]) tarjan(i); rep(i,1,n) w[belong[i]]+=f[i],g[belong[i]].push_back(i); ll resp=-1,resq=-1,flag=1; vector<int>v; rep(i,1,scc_cnt){ if(g[i].size()==1){ if(g[i][0]==f[g[i][0]]){ if(resp==-1){ resp=1,resq=w[i]; } else{ if(resp*w[i]!=resq*1){ flag=0;break; } } } } else if(g[i].size()>1) { if(resp==-1){ resp=g[i].size(),resq=w[i]; } else{ if(resp*w[i]!=resq*g[i].size()){ flag=0;break; } } } } if(flag) puts("YES"); else puts("NO"); } return 0; }