【BZOJ 1005】[HNOI2008]明明的烦恼(暴力化简法)
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1005
【题意】
中文题
【题解】
一棵节点上标有序号的树会和一个prufer数列唯一对应;
这个prufer数列可以这样获得;
每次找到序号最小的叶子节点;
然后把它删掉;
将与之相连的那个点加入数列的尾端;
重复上述操作直到只剩下两个节点为止;
即最后
一棵n个节点的树对应了一个长度为n-2的数列;
eg:
比如说这个图;
最小叶节点为2,删除2,将3计入序列
最小叶节点为4,删除4,将5计入序列
最小叶节点为5,删除5,将1计入序列
最小叶节点为1,删除1,将3计入序列
图中只剩下两个节点,退出
于是得到这棵树的Prufer序列为{3,5,1,3}
容易发现;
序列中某个数字出现的次数,就是它的度数-1;
且一个prufer序列(有序数列)也唯一对应了一棵树;
假设题目所给的n个节点,那些d[i]!=-1的每个节点的所需度数减去1后的总和为tot;
设有特定度数的节点个数为y,然后令没有特殊需要的节点个数为m
这样,我们相当于在n-2个空格当中选择tot个位置去放那些需要的y个节点;
那就是个组合问题了;
先在n-2个空格中选tot个位置;
即C(n-2,tot);······①
然后对于第i个节点,他要在位置里面选d[i]-1个空格放进去;
即
C(tot,d[i]-1]);·····②
然后对于第i+1个节点;
C(tot-(d[i]-1),d[i+1]-1);····③
…
然后将①②③….全部乘起来就是有特殊需求的节点的答案了;
至于剩下的m个没有特殊需求的节点;
在剩余的n-2-tot个位置里面;每个位置都有m个选择;
即m^(n-2-tot);
也乘上去就好;
最后全部乘在一起;
化简后就变为
【m^(n-2-tot)* (n-2)!】/【(n-2-tot)!* (d[1]-1)!*(d[2]-1)!……(d[n]-1)!】;
因为是方案,所以最后肯定可以约成整数;
所以问题就变成将n!质因数分解了;
(1..n每个数都质因数分解一下);
可以考虑分母和分子对最后结果的质因数分解形式的贡献;
分子的质因子对最后结果的相应质因子的指数的贡献是+1的;
而分母的质因子对最后结果的相应质因子的指数的贡献肯定是-1的;
有几个就减去相应的次数或加上相应的次数就好;
(需要写高精度);
(下一篇有更好的化简方法);
【完整代码】
/**************************************************************
Problem: 1005
User: chengchunyang
Language: C++
Result: Accepted
Time:36 ms
Memory:1304 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1100;
int n,d[N],m,tot,cnt[N];
int ans[N],len = 1;
void go(int t,int x)
{
for (int i = 2;i*i<=t;i++)
while (t%i==0)
{
cnt[i]+=x;
t/=i;
}
cnt[t]+=x;
}
void cheng(int p)
{
int x = 0;
rep1(i,1,len)
{
ans[i] = ans[i]*p+x;
x = ans[i]/10;
ans[i]%=10;
}
while (x>0)
{
ans[++len] = x;
x = ans[len]/10;
ans[len]%=10;
}
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);
rep1(i,1,n)
{
rei(d[i]);
if (d[i]==0) return puts("0"),0;
if (d[i]==-1)
m++;
else
d[i]--,tot+=d[i];
}
if (n-2<tot)
return puts("0"),0;
rep1(i,1,n-2)
go(i,1);
rep1(i,1,n-2-tot)
go(i,-1);
rep1(i,1,n)
rep1(j,1,d[i])
go(j,-1);
ans[1] = 1;
rep1(i,2,n)
rep1(j,1,cnt[i])
cheng(i);
rep1(i,1,n-2-tot)
cheng(m);
rep2(i,len,1)
printf("%d",ans[i]);
return 0;
}
【BZOJ 1005】[HNOI2008]明明的烦恼(暴力化简法)的更多相关文章
- BZOJ 1005 [HNOI2008] 明明的烦恼(组合数学 Purfer Sequence)
题目大意 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为 1 到 N 的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 N( ...
- BZOJ 1005: [HNOI2008]明明的烦恼 Purfer序列 大数
1005: [HNOI2008]明明的烦恼 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&&生成树计数
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2248 Solved: 898[Submit][Statu ...
- BZOJ 1005: [HNOI2008]明明的烦恼( 组合数学 + 高精度 )
首先要知道一种prufer数列的东西...一个prufer数列和一颗树对应..然后树上一个点的度数-1是这个点在prufer数列中出现次数..这样就转成一个排列组合的问题了.算个可重集的排列数和组合数 ...
- BZOJ 1005 [HNOI2008]明明的烦恼 (Prufer编码 + 组合数学 + 高精度)
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5786 Solved: 2263[Submit][Stat ...
- BZOJ 1005 [HNOI2008]明明的烦恼 purfer序列,排列组合
1005: [HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少 ...
- bzoj 1005 [HNOI2008] 明明的烦恼 (prufer编码)
[HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5907 Solved: 2305[Submit][Status][Di ...
- BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)
http://www.lydsy.com/JudgeOnline/problem.php?id=1005 题意: Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标 ...
- BZOJ.1005.[HNOI2008]明明的烦恼(Prufer 高精 排列组合)
题目链接 若点数确定那么ans = (n-2)!/[(d1-1)!(d2-1)!...(dn-1)!] 现在把那些不确定的点一起考虑(假设有m个),它们在Prufer序列中总出现数就是left=n-2 ...
随机推荐
- 《Exception》第八次团队作业:Alpha冲刺(第二天)
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 1.掌握软件测试基础技术.2.学习迭代式增量软 ...
- 浅谈optparse 解析命令行参数库
使用的背景 在工作中我们经常要制定运行脚本的一些参数,因为有些东西是随着我么需求要改变的,所以在为们写程序的时候就一定不能把写死,这样我们就要设置参数 在python中我们可以通过sys 模板的arg ...
- JAVA 重载方法,参数为NULL时,调用的处理 (精确性原则)
引子:大家可以思考一下下面程序的输出结果 public class TestNull { public void show(String a){ System.out.println("St ...
- java中 flush()方法的作用
flush() 是清空,而不是刷新啊.一般主要用在IO中,即清空缓冲区数据,就是说你用读写流的时候,其实数据是先被读到了内存中,然后用数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还 ...
- jquery weui ajax滚动加载更多
手机端使用jquery weui制作ajax滚动加载更多. 演示地址:http://wx.cnkfk.com/nuol/static/fpage.html 代码: <!DOCTYPE html& ...
- (插播)关于使用jenkins + unity +Xcode 来进行自己主动打包的处理。
近期了解了下jenkins流程化服务的东西,个人感觉jenkins是一个非常方便的工具.主要是方便.设置好流程性得命令.仅仅需确定下就能够达到自己主动化. 减轻了错误得发生和简化了带来的复杂得步骤.今 ...
- dotnet core test with NUnit
https://github.com/nunit/dotnet-test-nunit if you are using Visual Studio. Your project.json in your ...
- c语言运算符优先级与while循环案例
sizeof可以获取数据类型的内存中的大小(字节) #include <stdio.h> #include <stdlib.h> // standared 标准 // inpu ...
- Pocket英语语法---五、形式主语是怎么回事
Pocket英语语法---五.形式主语是怎么回事 一.总结 一句话总结:1.to不定式或动名词可以在主语的位置上,但一般用it代替它做形式主语.这种情况it叫形式主语. It's a great ho ...
- poj--2549--Sumsets(二分查找)
Sumsets Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit Statu ...