P4708 painting (Burnside) (Combinatorics)

Portal

Consider b u r n s i d e burnside count enumeration n ! n! species substitution, determined fixed point number in each permutation

First consider a weakened version of the title, is no label-free number to the map

Replacement of the role we have to point to the edge

The replacement of painted many rings, find an edge in either a replacement or a different permutation

In a fixed point number and substitution in different permutations respectively seek

The number of points within a fixed permutation is n 2 \frac{n}{2} , Consider if there are side ( x , x + t ) (x,x+t) , then there must be edge ( x + 1 , x + t + 1 ) . . . (x+1,x+t+1)... And so on, and considering t t and n t n-t It is the equivalent of

In different permutations, considering the size of two replacement A , B A,B , then one side will come out l c m ( A , B ) lcm(A,B) edges, thus actually fixed point number g c d ( A , B ) gcd(A,B)

These equivalence classes may occur can not occur, the contribution of the answer is 2 c n t 2^{cnt}

Found only related to the size and displacement, violence enumeration split, count the number of programs each split

A number of solutions prior arrangement n ! n! , the contribution of a loop is 1 l e n \ Frac {1} {len} Disorder between cycles of the same size, there is a 1 c n t [ i ] ! \frac{1}{cnt[i]!} Contributions

Consider this a stronger restriction Euler

I.e., the degree of each point is an even number

Also considered a substitution within the side
where the length is odd 2 l + 1 2*l+1 , all the displaced are on the point of impact does not appear even number, you can regardless of
if the length is even 2 l 2*l , wherein l 1 l-1 not a fixed point on the parity is not affected, and the last to take all diagonal points fixed point causes all degrees + 1

Consider edge between a replacement
for a A A influence the degree that point B g c d ( A , B ) \frac{B}{gcd(A,B)} ,Correct B B influence is A g c d ( a , b ) \frac{A}{gcd(a,b)}

We now find that the contribution can first take on will not be affected 2 c n t 2^{cnt}

Then you can have d i d_i In the first method of the i-th degree of substitution of all + 1, e u , v e_ {u, v} The method u , v u, v Replacement of all degree + 1

Then the number of such programs is the desire to meet the limits, can be exclusive or matrix Gaussian elimination, the number of contributions to the final element consisting of

But there are even better properties

We now e u , v e_ {u, v} Communication block form, just find a spanning tree, the spanning tree outer side pick, pick points other than the root

Found root side of the tree and corresponds to the only viable solution

Points to n n , selected number of points s s number selected side is m m , a communication block

Program number is 2 m ( n 1 ) + m a x ( 0 , ( s 1 ) ) 2^{m-(n-1)+max(0,(s-1))}

With disjoint-set to maintain

The main demand is the fixed point number, consider a fixed point or displacement between the displacement, violence enumerate the number of split multiplier scheme
quickly calculated the number of feasible solution by constructing a spanning tree, very clever

#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int ksm(int a, int b){ int ans = 1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans = mul(ans, a); return ans; }
void Add(int &a, int b){ a = add(a, b); }
cs int N = 55;
int gcd(int a, int b){ return !b ? a : gcd(b, a % b); }
int n, ans, inv[N], g[N][N];
int fa[N], sm[N]; 
int find(int x){ return x == fa[x] ? x : fa[x] = find(fa[x]); }
int loop[N], ct[N], now;
int calc(){
	int res = 0;
	for(int i = 1; i <= now; i++) fa[i] = i, sm[i] = 0;
	for(int i = 1; i <= now; i++){
		int v = loop[i]; res += ((v - 1) >> 1);
		if(!(v&1)) sm[i] = 1;
	}
	for(int i = 1; i <= now; i++){
		for(int j = i+1; j <= now; j++){
			int u = loop[i], v = loop[j], gc = g[u][v];
			int a = (u/gc) & 1, b = (v/gc) & 1;
			if(a && b) fa[find(i)] = find(j), res += gc;
			if(a && !b) sm[j] += gc;
			if(!a && b) sm[i] += gc;
			if(!a && !b) res += gc; 
		} 
	}
	for(int i = 1; i <= now; i++)
	if(find(i) == i){
		++res; res += sm[i] == 0 ? 0 : sm[i] - 1;
	} else sm[find(i)] += sm[i];
	res -= now; return ksm(2, res);
}
void dfs(int las, int rest, int coef){
	if(!rest){ Add(ans, mul(coef, calc())); return; }
	for(int i = min(las, rest); i; i--){
		++ct[i]; loop[++now] = i;
		dfs(i, rest - i, mul(coef, mul(inv[i], inv[ct[i]])));
		--ct[i]; --now;
	}
}
int main(){
	cin >> n; inv[0] = inv[1] = 1;
	for(int i = 2; i <= n; i++) inv[i] = mul(Mod-Mod/i, inv[Mod%i]);
	for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) g[i][j] = gcd(i, j);
	dfs(n, n, 1);
	cout << ans; return 0;
}
发布了610 篇原创文章 · 获赞 94 · 访问量 5万+

Guess you like

Origin blog.csdn.net/sslz_fsy/article/details/103431173