1089: [SCOI2003]严格n元树

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 762  Solved: 387
[Submit][Status]

Description

如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树。例如,深度为2的严格2元树有三个,如下图:

给出n, d,编程数出深度为d的n元树数目。

Input

仅包含两个整数n, d( 0   <   n   <   =   32,   0  < =   d  < = 16)

Output

仅包含一个数,即深度为d的n元树的数目。

Sample Input

【样例输入1】
2 2

【样例输入2】
2 3

【样例输入3】
3 5

Sample Output

【样例输出1】
3

【样例输出2】
21

【样例输出2】
58871587162270592645034001

HINT

Source

题解:

先说一下此题我的想法(尽管没有A掉。。。)

考虑递推解此题:

设f[i]表示深度为i的严格n元树的数目,g[i]表示深度为(1--i)的严格n元树的数目。

则我们有如下递推式:

1.f[i]=g[i-1]^n-g[i-2]^n

2.g[i]=g[i-1]+f[i]

第二个是显然的,我们来说一下第一个是怎么来的。

因为我们从i-1递推到i,所以考率在n棵子树上加一个根节点,其余为原先的子树

因为要保证这棵树的深度达到n,所以至少有一个子树的深度达到n-1,

所以每个子树可以有g[i-1]种形态,n棵就是g[i-1]^n,然后去掉不合法的,

不合法的就是每个子树的深度都在1--i-2,即有g[i-2]种选择,也就是 g[i-2]^n

然后如果我们使用累加法的话可以发现 g[i]=g[i-1]^n+1,貌似很简单了?

TLE!!!尽管没有试,但我想是这样的,因为这个复杂度的话,ans必须<=4000位,看起来貌似不可能那么少。。。

高精度乘高精度太浪费时间了,我暂时没有想到好的解决办法。

贴一下上面的代码(没有用累加法)

 #include<cstdio>

 #include<cstdlib>

 #include<cmath>

 #include<cstring>

 #include<algorithm>

 #include<iostream>

 #include<vector>

 #include<map>

 #include<set>

 #include<queue>

 #include<string>

 #define inf 1000000000

 #define maxn 50

 #define maxm 500000

 #define eps 1e-10

 #define ll long long

 #define pa pair<int,int>

 #define for0(i,n) for(int i=0;i<=(n);i++)

 #define for1(i,n) for(int i=1;i<=(n);i++)

 #define for2(i,x,y) for(int i=(x);i<=(y);i++)

 #define for3(i,x,y) for(int i=(x);i>=(y);i--)

 #define mod 10000

 using namespace std;

 inline int read()

 {

     int x=,f=;char ch=getchar();

     while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}

     while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}

     return x*f;

 }
int n,m,f[maxn][maxm],g[][maxm],t[maxm],c[maxm];
inline void writeln(int *a)
{
cout<<a[a[]];
for3(i,a[]-,)cout<<a[i];cout<<endl;
}
inline void update(int *a)
{
for1(i,a[])
{
a[i+]+=a[i]/mod;
a[i]%=mod;
if(a[a[]+])a[]++;
}
}
inline void mul(int *a,int x)
{
for1(i,a[])a[i]*=x;
update(a);
}
inline void jia(int *a,int *b)
{
a[]=max(a[],b[]);
for1(i,a[])
{
a[i]+=b[i];
a[i+]+=a[i]/mod;
a[i]%=mod;
}
while(!a[a[]])a[]--;
}
inline void cheng(int *a,int *b)
{
memset(c,,sizeof(c));
for1(i,a[])
for1(j,b[])
{
c[i+j-]+=a[i]*b[j];
c[i+j]+=c[i+j-]/mod;
c[i+j-]%=mod;
}
c[]=a[]+b[]+;
while(!c[c[]]&&c[])c[]--;
memcpy(a,c,sizeof(c));
}
inline void jian(int *a,int *b)
{
for1(i,a[])
{
a[i]-=b[i];
if(a[i]<)a[i]+=mod,a[i+]-=;
}
while(!a[a[]])a[]--;
} int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read();m=read();
f[][f[][]=]=;
g[][g[][]=]=;
g[][g[][]=]=;
for2(i,,m)
{
f[i][f[i][]=]=;
for1(j,n)cheng(f[i],g[]);
t[t[]=]=;
for1(j,n)cheng(t,g[]);
jian(f[i],t);
jia(g[],f[i-]);
jia(g[],f[i]);
}
printf("%d",f[m][f[m][]]);
for3(i,f[m][]-,)printf("%04d",f[m][i]); return ; }

感觉不会再爱了,这居然就是正解QAQ

不会貌似别人解释的更简单,直接推g[i]的表达式也很简单。

妈蛋,数据范围给的太大了,和lydsy要过来数据发现全是非常小的T_T

我做了2天多,一直在对拍自己的程序为什么出错,AC的程序运行过程中答案为什么会越来越小,我的程序为什么10 15的点都跑不出来,而且位数剧增

今天才发现是别人的空间爆了啊。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

还以为是我的程序错了啊。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

看来我的推断没有错,如果数据范围真如题中所说,那么答案的位数就太大了。

我要去建议lydsy修改此题的题面,不要再像坑我一样坑了其他人。。。

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 500+100
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 10000
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
class bigg
{
public:
int num[maxn], len;
bigg()
{
memset(num,,sizeof(num));
len=;
}
bigg operator = (const bigg &b)
{
memset(num,,sizeof(num));
len=b.len;
for1(i,len)num[i]=b.num[i];
return(*this);
}
bigg operator = (int b)
{
memset(num,,sizeof());
if (b==)
{
len=;
return(*this);
}
len=;
while(b>)
{
num[++len]=b%mod;
b/=mod;
}
return (*this);
}
bigg operator * (const bigg &b)
{
bigg ans;
ans=;
if (len==&&num[]==||b.len==&&b.num[]==)
return ans;
ans.len=len+b.len-;
for1(i,len)
for1(j,b.len)
{
ans.num[i+j-]+=num[i]*b.num[j];
ans.num[i+j]+=ans.num[i+j-]/mod;
ans.num[i+j-]%=mod;
}
if (ans.num[ans.len+])ans.len++;
while(!ans.num[ans.len])ans.len--;
return ans;
}
bigg operator - (const bigg &b)
{
bigg ans;
ans=;
ans.len=len;
for1(i,len)
{
ans.num[i]+=num[i]-b.num[i];
if (ans.num[i]<)
{
ans.num[i+]--;
ans.num[i]+=mod;
}
}
while (ans.len>&&!ans.num[ans.len]) ans.len--;
return ans;
}
bigg operator + (const bigg &b)
{
bigg ans;
ans=;
ans.len=max(len,b.len);
for1(i,ans.len)
{
ans.num[i]+=num[i]+b.num[i];
ans.num[i+]=ans.num[i]/mod;
ans.num[i]%=mod;
}
if (ans.num[ans.len+])ans.len++;
return ans;
}
void print()
{
printf("%d",num[len]);
for3(i,len-,)printf("%04d",num[i]);
printf("\n");
}
}; int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n, deep;
scanf("%d%d", &n, &deep);
if (deep == )
{
printf("1\n");
return ;
}
bigg fpre, fnow, f1;
fpre=,f1=;
for1(i,deep)
{
fnow=;
for1(j,n)fnow=fnow*fpre;
fnow=fnow+f1;
if (i!= deep) fpre=fnow;
}
fnow=fnow-fpre;
fnow.print();
return ;
}

不过还是有几点收获的:

1.捞到一个高精度模版

2.class里数组要开小

BZOJ1089: [SCOI2003]严格n元树的更多相关文章

  1. bzoj1089 [SCOI2003]严格n元树(dp+高精)

    1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1899  Solved: 954[Submit][Statu ...

  2. [BZOJ1089][SCOI2003]严格n元树(递推+高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...

  3. BZOJ1089:[SCOI2003]严格n元树(DP,高精度)

    Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d (根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严 ...

  4. BZOJ1089 [SCOI2003]严格n元树 【dp + 高精】

    Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d (根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严 ...

  5. 【BZOJ1089】[SCOI2003]严格n元树(高精度,动态规划)

    [BZOJ1089][SCOI2003]严格n元树(高精度,动态规划) 题面 BZOJ 洛谷 题解 设\(f[i]\)表示深度为\(i\)的\(n\)元树个数.然后我们每次加入一个根节点,然后枚举它的 ...

  6. BZOJ 1089: [SCOI2003]严格n元树

    1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1591  Solved: 795[Submit][Statu ...

  7. bzoj 1089 [SCOI2003]严格n元树(DP+高精度)

    1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1250  Solved: 621[Submit][Statu ...

  8. SCOI2003 严格N元树

    SCOI2003 严格N元树 Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d (根的深度为0),那么我们称它为一棵深度为d的 ...

  9. 【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1089 题意:求深度为d的n元树数目.(0<n<=32, 0<=d<=16) ...

随机推荐

  1. 电脑上已经安装mysql之后安装wamp,wamp中的mysql无法启动的解决办法

    Wampserver安装完成后无法启动MySQL这有可能是你之前安装过MysqL,因为wampserver内置MySQL.解决的方法就是配置环境变量. 找到我的电脑或计算机右键,打开属性,然后打开高级 ...

  2. RequireJS入门(三)

    这篇来写一个具有依赖的事件模块event.event提供三个方法bind.unbind.trigger来管理DOM元素事件. event依赖于cache模块,cache模块类似于jQuery的$.da ...

  3. [深入react] 4.牛逼闪闪的虚拟DOM

    React.createElement嵌套后的结果就是虚拟dom,虚拟dom听着很高端,其实就是一个json,类似: { type:'div', props:{ className:"box ...

  4. javascript实现限制上传文件的大小

    目录 基本思路 示例 [一].基本思路 在FireFox.Chrome浏览器中可以根据document.getElementById(“id_file”).files[0].size 获取上传文件的大 ...

  5. Github 开源编辑器 ATOM 已开放下载

    Update:2014-09-08 Atom 于5月6日正式开放下载(遗憾的是只有 MAC 版本),并且在 MIT 协义下开源,从界面可以看出,这款软件很像 Sublime Text,不过由于她的开源 ...

  6. 零基础学习云计算及大数据DBA集群架构师【Linux系统\网络服务及安全配置2015年1月8日周五】

    考试考一天,得分94,最后一题防火墙当时还没搞明白 考题如下: 注意事项: .确保在重启主机后所有配置仍然生效. .selinux 必须为Enforing 模式,防火墙必须开始.默认策略必须清空. . ...

  7. (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换

    一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...

  8. EF中使用SqlQuery进行参数化查询时抛出异常

    EF中使用带参数的SqlQuery进行查询时,抛出"另一个 sqlparametercollection 中已包含 sqlparameter"异常. 这是由于SqlParamert ...

  9. 如何快速恢复MyEclipse的默认主题

    这里天在研究主题,到网上找了一些主题导入,可是有一部分主题导入后不能通过preference选项进行恢复默认主题!那怎么办?有没有别的办法! 在网上找了一些答案,有更改工作空间的办法,也有替换.set ...

  10. 打破C++ Const 的规则

    从一个C++菜鸟改函数开始 CString MyClass::GetStringValue() const { return m_strValue; } 这个值可能还没有赋值,好吧,那么我先判断是不是 ...