【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)
http://www.lydsy.com/JudgeOnline/problem.php?id=1089
题意:求深度为d的n元树数目。(0<n<=32, 0<=d<=16)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const double PI=acos(-1.0);
struct big {
static const int N=10005;
static const ll M=10000000;
ll a[N];
void clr() { memset(a, 0, sizeof(ll)*(a[0]+1)); a[0]=1; }
void upd() { int len=a[0]; while(len>1 && a[len]==0) --len; a[0]=len; }
big() { a[0]=1; memset(a, 0, sizeof a); }
big(ll k) { a[0]=1; memset(a, 0, sizeof a); *this=k; }
big(const big &k) { a[0]=1; memset(a, 0, sizeof a); *this=k; }
big(char *k) { a[0]=1; memset(a, 0, sizeof a); *this=k; }
big & operator=(ll x) {
clr(); int len=0;
if(x==0) len=1;
while(x) a[++len]=x%M, x/=M;
a[0]=len;
return *this;
}
big & operator=(char *s) {
clr();
int n=strlen(s), len=1; ll k=1;
for3(i, n-1, 0) {
a[len]+=k*(s[i]-'0');
k*=10;
if(k>=M) { k=1; ++len; }
}
a[0]=len;
return *this;
}
big & operator=(const big &x) { clr(); memcpy(a, x.a, sizeof(ll)*(x.a[0]+1)); return *this; }
big & operator+(const big &x) {
static big t;
t.clr();
int len=max(x.a[0], a[0]), i=1; ll k=0;
for(; i<=len || k; ++i) {
t.a[i]=a[i]+x.a[i]+k;
k=t.a[i]/M;
if(t.a[i]>=M) t.a[i]%=M;
}
t.a[0]=i; t.upd();
return t;
}
big & operator-(const big &x) {
static big t;
t.clr();
for1(i, 1, a[0]) {
t.a[i]+=a[i]-x.a[i];
if(t.a[i]<0) --t.a[i+1], t.a[i]+=M;
}
t.a[0]=a[0]; t.upd();
return t;
}
big & operator*(const big &x) {
static big t;
t.clr();
fft(a+1, x.a+1, t.a+1, a[0], x.a[0], t.a[0]);
t.upd();
return t;
}
// big & operator*(const big &x) {
// static big t;
// t.clr();
// for1(i, 1, a[0]) for1(j, 1, x.a[0]) t.a[i+j-1]+=a[i]*x.a[j];
// int len=a[0]+x.a[0]-1, i=1; ll k=0;
// for(; i<=len || k; ++i) {
// t.a[i]+=k;
// k=t.a[i]/M;
// if(t.a[i]>=M) t.a[i]%=M;
// }
// t.a[0]=i; t.upd();
// return t;
// }
big & operator*(const ll &x) { static big t; t=x; t=(*this)*t; return t; }
big & operator+(const ll &x) { static big t; t=x; t=(*this)+t; return t; }
void P() {
printf("%lld", a[a[0]]);
for3(i, a[0]-1, 1) printf("%07lld", a[i]);
} struct cp {
double r, i;
cp(double _r=0.0, double _i=0.0) : r(_r), i(_i) {}
cp operator + (const cp &x) { return cp(r+x.r, i+x.i); }
cp operator - (const cp &x) { return cp(r-x.r, i-x.i); }
cp operator * (const cp &x) { return cp(r*x.r-i*x.i, r*x.i+i*x.r); }
};
int rev[N];
void init(int &len) {
int k=1, t=0;
while(k<len) k<<=1, ++t;
len=k;
rep(i, len) {
k=t; int ret=0, x=i;
while(k--) ret<<=1, ret|=x&1, x>>=1;
rev[i]=ret;
}
}
void dft(cp *a, int n, int flag) {
static cp A[N];
rep(i, n) A[i]=a[rev[i]];
rep(i, n) a[i]=A[i];
int m, i, j, mid;
cp t, u;
for(m=2; m<=n; m<<=1) {
cp wn(cos(2.0*PI/m*flag), sin(2.0*PI/m*flag));
for(i=0; i<n; i+=m) {
cp w(1.0); mid=m>>1;
for(j=0; j<mid; ++j) {
u=a[i+j+mid]*w, t=a[i+j];
a[i+j]=t+u;
a[i+j+mid]=t-u;
w=w*wn;
}
}
}
if(flag==-1) rep(i, n) a[i].r/=n;
}
void fft(const ll *a, const ll *b, ll *c, const ll &la, const ll &lb, ll &lc) {
static cp x[N], y[N];
int len=la+lb-1;
init(len);
rep(i, len) x[i].r=a[i], x[i].i=0;
rep(i, len) y[i].r=b[i], y[i].i=0;
dft(x, len, 1); dft(y, len, 1);
rep(i, len) x[i]=x[i]*y[i];
dft(x, len, -1);
rep(i, len) c[i]=x[i].r+0.5;
rep(i, len) c[i+1]+=c[i]/M, c[i]%=M;
lc=len+1;
}
};
big f[35], k, r;
int main() {
int n=getint(), d=getint();
if(!d) { puts("1"); return 0; }
f[0]=1;
for1(i, 1, d) {
r=1; k=f[i-1];
int t=n;
while(t) { if(t&1) r=r*k; t>>=1; k=k*k; }
f[i]=r+1;
}
r=f[d]-f[d-1];
r.P();
return 0;
}
想了好久的递推式,,,然后放弃了QAQ
神思路!orz
首先我们设$f[i]$表示深度最大为i的n元树的数目,注意,是最大深度为i!
那么易得递推式
f[i]=f[i-1]^n+1
前面表示子树的情况乘积,后面表示树为1层!因为1层是合法的!即没有子女!
然后答案就是
f[d]-f[d-1]
!!!为什么要剪掉呢?因为看我们的转移,并不是深度为i,而是深度最大为i,那么为什么要这样减呢?理由很简单吧。。。f[d]表示深度最大为d的数目,f[d-1]表示深度最大为d-1的数目,那么我们只要深度为d,那么剪掉之。。。
然后还要特判!!!!我没特判wa了好久!!!!
当d=0的时候。。。。。。。。。。答案=1。。
然后蒟蒻我打了个fft做乘法。。。可是比普通乘法还慢?不明觉厉QAQ
【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)的更多相关文章
- bzoj 1089 SCOI2003严格n元树 递推
挺好想的,就是一直没调过,我也不知道哪儿的错,对拍也拍了,因为数据范围小,都快手动对拍了也不知道 哪儿错了.... 我们定义w[i]代表深度<=i的严格n元树的个数 那么最后w[d]-w[d-1 ...
- bzoj 1089 [SCOI2003]严格n元树(DP+高精度)
1089: [SCOI2003]严格n元树 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1250 Solved: 621[Submit][Statu ...
- [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...
- BZOJ 1089: [SCOI2003]严格n元树
1089: [SCOI2003]严格n元树 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1591 Solved: 795[Submit][Statu ...
- BZOJ 1089 SCOI2003 严格n元树 动态规划+高精度
题目大意:定义一棵深度为d的严格n元树为根的深度为0,最深的节点深度为d,且每一个非叶节点都有恰好n个子节点的树 给定n和d,求深度为d的严格n元树一共同拥有多少种 此题的递推部分并不难 首先我们设深 ...
- bzoj 1089: [SCOI2003]严格n元树【dp+高精】
设f[i]为深度为i的n元树数目,s为f的前缀和 s[i]=s[i-1]^n+1,就是增加一个根,然后在下面挂n个子树,每个子树都有s[i-1]种 写个高精就行了,好久没写WA了好几次-- #incl ...
- 【noi 2.6_9280】&【bzoj 1089】严格n元树(DP+高精度+重载运算符)
题意:定义一棵树的所有非叶节点都恰好有n个儿子为严格n元树.问深度为d的严格n元树数目. 解法:f[i]表示深度为<=i的严格n元树数目.f[i]-f[i-1]表示深度为i的严格n元树数目.f[ ...
- BZOJ 1089 严格n元树 (递推+高精度)
题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就 ...
- 1089: [SCOI2003]严格n元树
好久没更新了..于是节操掉尽python水过本来就水的题.. n,d=map(int, raw_input().split()) if d==0: print 1 else: f=[1] for i ...
随机推荐
- 2015-2-10 Linux 知识
1.Linux系统中某个可执行文件属于root并且有setid,当一个普通用户mike运行这个程序时,产生的进程的有效用户和实际用户分别是____? A root mike B root rooy C ...
- 双参数Bellman-ford带队列优化类似于背包问题的递推
为方便起见,将Bellman-ford队列优化称为SPFA,= = 抓住 ZMF (ZMF.pas/c/cpp) 题目描述 话说这又是一个伸手不见五指的夜晚,为了机房的电子竞技事业永远孜孜不倦的 ZM ...
- Linux--YUM 安装 nginx php mysql
Linux--YUM 安装 nginx php mysql (2011-11-13 11:27:14) 转载▼ 标签: 杂谈 分类: Linux 1.先新建一个 repo # vi /etc/yum. ...
- catalog、scheme区别
按照SQL标准的解释,在SQL环境下Catalog和Schema都属于抽象概念,可以把它们理解为一个容器或者数据库对象命名空间中的一个层次,主要用来解决命名冲突问题.从概念上说,一个数据库系统包含多个 ...
- 《ASP.NET MVC4 WEB编程》学习笔记------RenderBody,RenderPage,RenderSection
ASP.NET MVC 3 已经正式发布了,现在估计许多人都在拼命学,我也不能例外,刚刚看到了一篇文章,介绍了三个非常有用的方法:RenderBody,RenderPage和RenderSection ...
- eclipse加速之禁用JS、jsp等文件的语法验证,eclipsejs
eclipse加速之禁用JS.jsp等文件的语法验证 去除eclipse的JS验证:将windows->preference->Java Script->Validator-> ...
- 【转】自动实时监控Windows2003服务器终端登录并发邮件和发短信通知
记得以前管理的一批windows服务器,一些开源程序做的web站点总会遭到入侵.然而就想找找看有没有办法可以知道服务器有没有被入侵.服务器在什么时候登陆过,如果登陆马上发邮件通知,感觉这种问题肯定有人 ...
- codeforces B. Sereja and Stairs 解题报告
题目链接:http://codeforces.com/problemset/problem/381/B 题目意思:给定一个m个数的序列,需要从中组合出符合楼梯定义 a1 < a2 < .. ...
- Ubuntu安装steam游戏平台的解决方案
steam是一个游戏平台,上面提供了很多收费和免费的游戏,在安装的过程中遇到了一些问题,所以把自己遇到的问题及解决方案分享出来供大家参考. 第一步:安装steam平台 sudo apt-get ins ...
- 完善DriveInfoEx源代码 获取计算机硬盘序列号
概述: 获取计算机硬盘序列号用途很多,在网上找到了一个C++的源代码DriveInfoEx(点这里查看).非常好的一个DLL,.NET项目可以直接引用,而且源代码里有示例. 但这个DLL在Win7非管 ...