Alice家里有一盏很大的吊灯。所谓吊灯,就是由很多个灯泡组成。只有一个灯泡是挂在天花板上的,剩下的灯泡都是挂在其他的灯泡上的。也就是说,整个吊灯实际上类似于一棵树。其中编号为1的灯泡是挂在天花板上的,剩下的灯泡都是挂在编号小于自己的灯泡上的。
现在,Alice想要办一场派对,她想改造一下这盏吊灯,将灯泡换成不同的颜色。她希望相同颜色的灯泡都是相连的,并且每一种颜色的灯泡个数都是相同的。
Alice希望你能告诉她,总共有哪些方案呢?
Alice是一个贪心的孩子,如果她发现方案不够多,或者太多了,就会很不高兴,于是她会尝试调整。对于编号为x(x≠1)的灯泡,如果原来是挂在编号为f[x]的灯泡上,那么Alice会把第x个灯泡挂到第 ( f[x] + 19940105 ) mod (x-1) + 1 个灯泡上。
由于九在古汉语中表示极大的数,于是,Alice决定只调整9次。对于原始状态和每一次调整过的状态,Alice希望你依次告诉她每种状态下有哪些方案。
第一行一个整数n,表示灯泡的数量。
接下来一行,有n-1个整数Ui,第i个数字表示第i+1个灯泡挂在了Ui个的下面。保证编号为1的灯泡是挂在天花板上的。数字之间用逗号‘,’隔开且最后一个数字后面没有逗号。
对于10种状态下的方案,需要按照顺序依次输出。
对于每一种状态,需要先输出单独的一行,表示状态编号,如样例所示。
之后若干行,每行1个整数,表示划分方案中每种颜色的灯泡个数。
按升序输出。
1 /*by SilverN*/
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cstdio>
6 #include<cmath>
7 using namespace std;
8 const int mxn=1200010;
9 int read(){
10 int x=0,f=1;char ch=getchar();
11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
13 return x*f;
14 }
15 int n;
16 int a[mxn],cnt=0;
17 int fa[mxn],num[mxn];
18 int c[mxn];
19 //void DFS(int u,int fa){
20 //}
21 void reset(){
22 for(int i=2;i<=n;i++){
23 fa[i]=(fa[i]+19940105)%(i-1)+1;
24 }
25 return;
26 }
27 void init1(){
28 int m=sqrt(n);
29 for(int i=1;i<=m;i++){
30 if(n%i==0){
31 a[++cnt]=i;
32 if(i*i!=n)a[++cnt]=n/i;
33 }
34 }
35 return;
36 }
37 void init(){
38 memset(c,0,sizeof c);
39 for(int i=1;i<=n;i++)num[i]=1;
40 return;
41 }
42 void solve(){
43 init();
44 int i,j;
45 for(i=n;i>=1;i--)
46 num[fa[i]]+=num[i];
47 for(i=1;i<=n;i++)c[num[i]]++;
48 for(i=1;i<=cnt;i++){
49 int x=a[i];//每种颜色x个灯泡
50 int res=0;
51 for(j=x;j<=n;j+=x){
52 res+=c[j];
53 }
54 if(n/x==res)printf("%d\n",x);
55 }
56 return;
57 }
58 int main(){
59 n=read();
60 init1();
61 int i,j;
62 for(i=2;i<=n;i++)fa[i]=read();
63 printf("Case #1:\n");
64 solve();
65 for(i=1;i<=9;i++){
66 printf("Case #%d:\n",i+1);
67 reset();
68 solve();
69 }
70 return 0;
71 }