ickchen2

zoj 3405 Counting Factor Trees

明显是一道水题,但确不会做
如果把数给分解了之后有n个质因子。那么就是求n个点可以有多少种二叉树,然后把这n个质因子放进去就行了
求多少种二叉树就是dp,放质因子就是一个可重排列数

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string>
  4 #include<vector>
  5 #include<map>
  6 #include<queue>
  7 #include<algorithm>
  8 #define M 1000
  9 #define clr(x) memset(x,0,sizeof(x))
 10 #define _clr(x) memset(x,-1,sizeof(x))
 11 #define fr(i,a,b) for(int i=a;i<b;++i)
 12 #define pf printf
 13 #define sf scanf
 14 #define pb push_back
 15 #define mp make_pair
 16 #define ll long long
 17 #define debug 1
 18 using namespace std;
 19 const int maxs=1000000;
 20 int pr[1000000],is[maxs+10],len;
 21 int e[1000000],cnt;
 22 void Frac(ll n)
 23 {
 24     cnt=0;
 25     fr(i,0,len)
 26     {
 27         if((ll)pr[i]*pr[i]>n)break;
 28         //pf("pr=%d\n",pr[i]);
 29         if(n%pr[i]==0)
 30         {
 31             e[cnt]=0;
 32             while(n%pr[i]==0)
 33             {
 34                 n/=pr[i];
 35                 ++e[cnt];
 36             }
 37             ++cnt;
 38         }
 39     }
 40     if(n>1)
 41     {
 42         e[cnt++]=1;
 43     }
 44 }
 45 void getPrime()
 46 {
 47     len=0;
 48     clr(is);
 49     for(int i=2;i<maxs;++i)
 50     {
 51         if(!is[i])
 52         {
 53             pr[len++]=i;
 54         }
 55         for(int j=0;j<len&&(ll)pr[j]*i<maxs;++j)
 56         {
 57             is[pr[j]*i]=1;
 58             if(i%pr[j]==0)break;
 59         }
 60     }
 61 }
 62 int p[1000000],exp[1000000],c;
 63 ll pow(int a,int b)
 64 {
 65     ll ret=1;
 66     while(b>0)
 67     {
 68         if(b&1){ret*=a;}
 69         a*=(ll)a;
 70         b>>=1;
 71     }
 72     return ret;
 73 }
 74 ll cal()
 75 {
 76     int tot=0;
 77     for(int i=0;i<cnt;++i)
 78     {
 79         tot+=e[i];
 80     }
 81     //pf("c:\n");
 82     //pf("tot=%d\n",tot);
 83     c=0;
 84     for(int i=0;i<len;++i)
 85     {
 86         if(pr[i]>tot)break;
 87         p[c]=pr[i];
 88         exp[c]=0;
 89         int tem=tot;
 90         while(tem>0)
 91         {
 92             exp[c]+=tem/p[c];
 93             tem/=p[c];
 94         }
 95        // pf("pc=%d expc=%d\n",p[c],exp[c]);
 96         ++c;
 97     }
 98     for(int i=0;i<cnt;++i)
 99     {
100         int ret=e[i];
101         for(int j=0;j<len;++j)
102         {
103             if(pr[j]>ret)break;
104             int pos=lower_bound(p,p+c,pr[j])-p;
105             int tem=ret;
106             while(tem>0)
107             {
108                 exp[pos]-=tem/pr[j];
109                 tem/=pr[j];
110             }
111         }
112     }
113     ll res=1;
114     for(int i=0;i<c;++i)
115     {
116         res*=pow(p[i],exp[i]);
117     }
118     return res;
119 }
120 ll dp[1000000];
121 ll dfs(int n)
122 {
123    // if(n>1000000)return 1;
124     if(dp[n])return dp[n];
125     ll ret=0;
126     for(int i=1;i<=n/2;++i)
127     {
128         ll tem=dfs(i)*dfs(n-i);
129         if(i!=n-i)tem*=2;
130         ret+=tem;
131     }
132     return dp[n]=max(ret,(ll)1);
133 }
134 
135 int main()
136 {
137 
138     int n;
139     getPrime();
140     clr(dp);
141     freopen("in.txt","r",stdin);
142     //freopen("out1.txt","w",stdout);
143     while(sf("%d",&n)>0)
144     {
145         //ft.clear();
146         Frac(n);
147         int tot=0;
148         fr(i,0,cnt)
149             tot+=e[i];
150         //pf("tot=%d\n",tot);
151         ll ans=dfs(tot);
152         ans*=cal();
153         pf("%lld\n",ans);
154     }
155 
156     return 0;
157 }
158 

posted on 2010-09-07 22:17 神之子 阅读(234) 评论(0)  编辑 收藏 引用 所属分类: zoj月赛


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜