Title:
In this paper, a tree is given, each node of the tree is colored with m colors, and different staining schemes are obtained. The two staining schemes are considered the same if and only if the nodes in the subtree are rotated or not. Rotation: this tree is very strange. In the subtree with u as its root, the child nodes of the generation of U form a similar ring structure. After rotating a unit, the subtree that was originally ranked first is ranked last, and the subtree that was originally ranked second is ranked first.
Train of thought:
Let's briefly introduce Polya's theorem
Let g = {P1, P2 ,pg}G={p1,p2,… , PG} is a permutation group of n objects. It is noted that c(pi)c(pi) is the number of cycles of permutation pipi. If the n objects are dyed with m colors, the number of different staining schemes is:
L=∑gi=1mc(pi)|G|L=∑i=1gmc(pi)|G|
Of course, I f this is not a simple dyeing, and some limitations may be involved, you can replace mc(pi)mc(pi) with the number of schemes f(i)f(i) dyed under permutation pipi. Because different cycles are independent of each other and the elements in the same cycle are dyed the same, f(i)f(i) is equal to the product of the number of staining schemes in each cycle.
Let's consider a subtree separately, what kind of permutation can be produced for a generation of child nodes of this subtree. First of all, it is sure to produce a fixed permutation. Next, it is considered whether the permutation can be produced by rotating ii units. If permutation can be generated, the subtrees of nodes in the same cycle must have the same shape (it can be the same shape after rotation). Therefore, tg[u][v] should be processed to indicate whether the subtrees u and V have the same shape. When we know what permutations there are, we can apply the formula.
Code:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 110
#define MO 1000000007
#define LL long long
int c,n,G[MAXN][MAXN],l;
char s[MAXN*20];
LL dp[MAXN],inv[MAXN*MAXN];
void Init(int u)//Construction tree
{
G[u][0]=0;
while(s[l]=='[')
{
if(s[l]=='[')
{
G[u][++G[u][0]]=++n;
l++,Init(n);
}
l++;
if(s[l]==',') l++;
}
}
int tg[MAXN][MAXN],vis[MAXN];
int check(int u,int v)//Check whether the shape of the two subtrees u and v are the same
{
if(tg[u][v]) return tg[u][v];
if(G[u][0]!=G[v][0]) return tg[u][v]=tg[v][u]=-1;
if(G[u][0]==0) return tg[u][v]=tg[v][u]=1;
for(int i=0;i<G[u][0];i++)
{
bool f=1;
for(int j=1;j<=G[v][0];j++)
{
int k=i+j;
if(k>G[v][0]) k-=G[v][0];
if(check(G[u][k],G[v][j])==-1)
{
f=0;
break;
}
}
if(f==1) return tg[u][v]=tg[v][u]=1;
}
return tg[u][v]=tg[v][u]=-1;
}
void Solve(int u)
{
dp[u]=(u==1)?1:c;
for(int i=1;i<=G[u][0];i++)
{
Solve(G[u][i]);
dp[u]*=dp[G[u][i]];
dp[u]%=MO;
}
int cnt=1;//Record how many replacements there are
for(int i=1;i<G[u][0];i++)//Enumerate how many units to rotate
{
memset(vis,0,sizeof vis);
bool flag=1;
LL num=c;
for(int j=1;j<=G[u][0];j++)
if(!vis[j])
{
int k=j;
do
{
vis[k]=1;
if(check(G[u][k],G[u][j])==-1)
{
flag=0;
break;
}
k+=i;
if(k>G[u][0]) k-=G[u][0];
}while(!vis[k]);
if(flag==0) break;
num*=dp[G[u][j]];
num%=MO;
}
if(flag)
{
cnt++;
dp[u]=(dp[u]+num)%MO;
}
}
dp[u]=dp[u]*inv[cnt]%MO;
}
int main()
{
inv[1]=1;
for(int i=2;i<MAXN*MAXN;i++)
inv[i]=1LL*(MO-MO/i)*inv[MO%i]%MO;
int tm;
scanf("%d",&tm);
for(int cs=1;cs<=tm;cs++)
{
memset(tg,0,sizeof tg);
scanf("%s%d",s,&c);
n=0,l=0;
Init(++n);
Solve(1);
printf("Case #%d: %d\n",cs,dp[1]);
}
}