Enumerate each permutation, find the number of methods that are shaded unchanged under each permutation, first find out the size of each loop, and then dynamically plan the number of methods corresponding to using the given color.
Dp[i][j][k] Represents the number of methods that are processed to the current lap when r,b,g usage is i,j,k, knapsack thought.
#include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <string > #include <algorithm> #include <map> #include <queue> #include <vector> #include <cmath > #include namespace std;typedef long long ll;const int N = <utility>using, INF = 0x3f3f3f3f; #define MS (A, num) memset (A, num, sizeof (a)) #define PB (a) push_back (a) #define for (I, n) for (int i = 0; i < n; i++) int R, G, B, M, p, N;int Dis[n][n];bool Vis[n]; LL Dp[n][n][n]; ll EXT_GCD (ll a,ll b,ll &x,ll &y) {//Extended Euclid if (b==0) {x=1, y=0; return A;} LL ret= EXT_GCD (b,a%b,y,x); y-= a/b*x; return ret;} ll Inv (ll a,int m) {///d,x,y,t= ll (LL) m; d= EXT_GCD (a,t,x,y); if (d==1) return (x%t+t)%t; return-1;} ll solve () {ll ans = 0; for (int x = 0; x < m; × X + +) {memset (Vis, 0, sizeof (VIS)); Vector<int> v; for (int i = 1; I <= n; i++) {if (!vis[i]) {int cnt = 0; int TP = i; while (!VIS[TP]) {cnt++; VIS[TP] = 1; TP = DIS[X][TP]; } v.push_back (CNT); }} memset (DP, 0, sizeof (DP)); Dp[0][0][0] = 1; for (int t = 0; t < v.size (), t++) {for (int i = r, I >= 0; i--) {for (int j = b; j >= 0; j--) {for (int k = g; k >= 0; k--) {if (i = = 0 && J = = 0 && k = = 0) {continue; } Dp[i][j][k] = 0; if (i >= v[t]) {dp[i][j][k] = (Dp[i][j][k] + dp[i-v[t]][j][k])% p; } if (J >= V[t]) {dp[i][j][k] = (Dp[i][j][k] + dp[i][j-v[t]][k])% P } if (k >= v[t]) {dp[i][j][k] = (dp[i][j][K] + dp[i][j][k-v[t]])% p; }}}}} ans = (ans + dp[r][b][g])% p; } ans = ans * INV (M, p)% p; return ans;} int main () {while (~SCANF ("%d%d%d%d", &r, &b, &g, &m, &p)) {n = R + B + G; bool F = 1; for (int i = 0; i < m; i++) {int cnt = 0; for (int j = 1; J <= N; j + +) {scanf ("%d", &dis[i][j]); if (dis[i][j] = = j) {cnt++; }} if (cnt = = N) {f = 0; }} if (f) {for (int i = 1; I <= n; i++) {dis[m][i] = i; } m++; } printf ("%lld\n", Solve ()); } return 0;}
BZOJ1004 [Hnoi2008]cards (Polya count)