题解:AT_abc470_f [ABC470F] Googol Swaps
由于是
于是,对于每个连通块,记
的乘积……吗?
我们发现,它还有一个问题,就是我们要操作恰好
于是我们发现,如果我们最后交换的次数少一次,我们就必须选择两个字母交换,由于它们一定不同,相当于这两个字母的排列从
:::success[Code]
#include<bits/stdc++.h>
using namespace std;
constexpr int mod=998244353;
constexpr int maxn=1010101;
int f[maxn];
#define find _find
__inline int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
vector<int> e[maxn];
long long fac[maxn];
int cnt[30];
__inline long long qpow(long long base,int p=mod-2){
long long ans=1;
while(p){
if(p&1)ans=ans*base%mod;
base=base*base%mod;
p>>=1;
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);
int n,m;cin>>n>>m;
fac[0]=1;
for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;
for(int i=1;i<=n;i++)f[i]=i;
string s;cin>>s;
for(int i=1;i<=m;i++){
int a,b;cin>>a>>b;
f[find(a)]=find(b);
}
for(int i=1;i<=n;i++)e[find(i)].push_back(s[i-1]);
long long ans=1;
bool flg=0;
for(int i=1;i<=n;i++){
sort(e[i].begin(),e[i].end());
memset(cnt,0,sizeof(cnt));
for(auto x:e[i])cnt[x-'a']++;
ans=ans*fac[e[i].size()]%mod;
for(int i=0;i<26;i++){
ans=ans*qpow(fac[cnt[i]])%mod;
if(cnt[i]>1)flg=1;
}
}
if(!flg)ans=ans*qpow(2)%mod;
cout<<ans<<'\n';
return 0;
}