Ex. Count Unlabeled Graphs
k = 1 的情况下,显然就是无标号图计数。
所以做法也必然不会弱于 原题。
回忆原题中,我们对点集的对称群,按照 cycle index 进行分类,再去生成对应的边置换群,再得到边置换群的 cycle index。不过看起来这里我们既要考虑边染色,还要考虑点染色,好在它们的结构都是用初始的点群的 cycle index 所决定的,可以一起参与计算。
最后再 简单冗斥 一下即可。
#include <lastweapon/number>
using namespace lastweapon;
const int N = int(5e1) + 9;
Int Fact[N]; VVI Partition; VI cur;
int n;
void gen(int n = ::n, int s = 1){
if (!n){
Partition.PB(cur);
}
else if (n >= s){
cur.PB(s); gen(n-s, s); cur.pop_back();
gen(n, s+1);
}
}
Int c(const VI P){
Int z = Fact[n]; int c = 0, l = P.front();
ECH(it, P){
z /= *it; if (*it != l){
z /= Fact[c]; l = *it;
c = 1;
}
else{
++c;
}
}
z /= Fact[c];
return z;
}
int g(const VI P){
REP(i, SZ(P)) {
w[i] = 0; vis[i] = 0;
adj[i].clear();
}
int z = 0; REP(i, SZ(P)){
z += P[i] / 2;
REP(j, i) z += __gcd(P[i], P[j]);
}
return z;
}
Int binom(int n, int m) {
return Fact[n] / (Fact[m] * Fact[n-m]);
}
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
int k; RD(n, k, MOD); Fact[0] = 1; REP_1(i, n) Fact[i] = Fact[i-1] * i;
gen();
Int z = 0; ECH(it, Partition) if (SZ(*it) >= k) {
Int zz = 0;
REP(i, k) {
Int d = binom(k, i) * pow(Int(k-i), SZ(*it));
if (i&1) zz -= d; else zz += d;
}
z += zz * c(*it) * pow(Int(2), g(*it));
}
z /= Fact[n];
cout << z << endl;
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
