题意:
解法:
根据题目要求,选择了i就必须选择a[i],
那么构造一条i->a[i]的边.
由于每个点都有出边,因此图一定会出现环,
为了保证题目中a!=b时,f[a]!=f[b],
因此对于每个基图连通块,
只能选择环的那一块,如图:
发现每个基图连通块只有一种选法后,
可以用并查集计算有多少个基图连通块.
假设有cnt个连通块,那么答案为2^cnt-1,
减1是为了减去空集.
code:
#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
const int mod=998244353;
int pre[maxm];
int n;
int ffind(int x){
return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
pre[i]=i;
}
for(int i=1;i<=n;i++){
int x;cin>>x;
pre[ffind(x)]=ffind(i);
}
int ans=1;
for(int i=1;i<=n;i++){
if(pre[i]==i){
ans=ans*2%mod;
}
}
ans=(ans-1+mod)%mod;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
solve();
return 0;
}