bzoj 1005 1211 prufer序列总结
两道题目大意都是根据每个点的度数来构建一棵无根树来确定有多少种构建方法
这里构建无根树要用到的是prufer序列的知识
先很无耻地抄袭了一段百度百科中的prufer序列的知识:
将树转化成Prufer数列的方法
Prufer数列以右边的树为例子,首先在所有叶子节点中编号最小的点是2,和它相邻的点的编号是3,将3加入序列并删除编号为2的点。接下来删除的点是4,5被加入序列,然后删除5,1被加入序列,1被删除,3被加入序列,此时原图仅剩两个点(即3和6),Prufer序列构建完成,为{3,5,1,3}
将Prufer数列转化成树的方法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
#define pii pair<int,int>
int n , w[] , num[];
vector<pii> v[]; void solve(int m)
{
if(m==) return;
int tmp = m;
for(int i= ; i<=m ; i++){
if(m%i==){
int cnt = ;
while(m%i==){
m/=i;
cnt++;
}
v[tmp].push_back(make_pair(i , cnt));
}
}
if(m>) v[tmp].push_back(make_pair(m , ));
// for(int i=0 ; i<v[tmp].size() ; i++) cout<<v[tmp][i].first<<" "<<v[tmp][i].second<<endl;
}
void init()
{
for(int i= ; i<= ; i++) solve(i);
}
void update(int k , int flag)
{
for(int i= ; i<v[k].size() ; i++){
pii u=v[k][i];
num[u.first]+=u.second*flag;
}
}
void mul(long long &ans , int k , int tim)
{
for(int i= ; i<=tim ; i++) ans=ans*k;
}
int main()
{
// freopen("Sweet.in" , "r" , stdin);
init();
while(~scanf("%d" , &n)){
memset(num , , sizeof(num));
int sum= , flag=true;
for(int i= ; i<=n ; i++){
scanf("%d" , &w[i]);
if(w[i]==) flag = false;
sum+=w[i]-;
for(int j= ; j<=w[i]- ; j++) update(j , -);
}
if(n== && w[]==){
cout<<<<endl;
continue;
}
if(sum!=n- || n== || flag==false){
cout<<<<endl;
continue;
}
for(int i= ; i<=n- ; i++) update(i , );
long long ans = ;
for(int i= ; i<=n- ; i++){
if(num[i]) mul(ans , i , num[i]);
}
cout<<ans<<endl;
}
return ;
}
bzoj1211
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define N 1005
int n , a[N] , cnt[N];
int ans[N*] , l1;
int mul[N] , l2;
int tmp[N*]; void fenjie(int x , int flag)
{
for(int i= ; i*i<=x ; i++){
while(x%i==){
cnt[i]+=flag;
x/=i;
}
}
if(x>) cnt[x]+=flag;
} void solveC(int a , int b) //C(n-2 , sum)
{
for(int i= ; i<=b ; i++) fenjie(i , -);
for(int i=a ; i>a-b ; i--) fenjie(i , );
} void change(int x)
{
l2 = ;
while(x){
mul[l2++] = x%;
x/=;
}
} void cal()
{
memset(tmp , , sizeof(tmp));
int len = ;
for(int i= ; i<l2 ; i++){
for(int j= ; j<l1 ; j++){
int cur = i+j;
len = max(len , cur+);
tmp[cur] += ans[j]*mul[i];
}
}
for(int i= ; i<len ; i++){
if(tmp[i]>=){
len= max(len , i+);
tmp[i+] += tmp[i]/;
tmp[i] %= ;
}
}
for(int i= ; i<len ; i++) ans[i] = tmp[i] , l1 = len;
} void print()
{
for(int i=l1- ; i>= ; i--) printf("%d" , ans[i]);
printf("\n");
}
int main()
{
// freopen("a.in" , "r" , stdin);
while(~scanf("%d" , &n)){
memset(cnt , , sizeof(cnt));
int w = , sum = ;
bool flag = true;
for(int i= ; i<=n ; i++){
scanf("%d" , &a[i]);
if(a[i]==) flag=false;
if(a[i]<) w++;
else{
sum+=a[i]-;
for(int j= ; j<=a[i]- ; j++) fenjie(j , -);
}
}
if(n== && a[]==){
cout<<<<endl;
continue;
}
solveC(n- , sum);
if(n== || sum>n- || flag==false) cout<<<<endl;
else{
for(int i= ; i<=sum ; i++) fenjie(i, );
int cnt = n--sum;
for(int i= ; i<=cnt ; i++) fenjie(w , );
}
// for(int i=1 ; i<=10 ; i++) cnt[i]++;
ans[] = , l1=;
for(int i= ; i<=n ; i++){
if(cnt[i]){
change(i);
for(int j= ; j<=cnt[i] ; j++){
cal();
}
}
}
print();
}
return ;
}
bzoj1005
bzoj 1005 1211 prufer序列总结的更多相关文章
- [HNOI2004]树的计数 BZOJ 1211 prufer序列
题目描述 输入输出格式 输入格式: 输入文件第一行是一个正整数n,表示树有n个结点.第二行有n个数,第i个数表示di,即树的第i个结点的度数.其中1<=n<=150,输入数据保证满足条件的 ...
- [BZOJ1005][HNOI2008]明明的烦恼 数学+prufer序列+高精度
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int N; ...
- 【BZOJ 1211】 1211: [HNOI2004]树的计数 (prufer序列、计数)
1211: [HNOI2004]树的计数 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2468 Solved: 868 Description 一 ...
- [HNOI2008][bzoj 1005]明明的烦恼(prufer序列)
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7121 Solved: 2816[Submit][Stat ...
- BZOJ 1211 HNOI2004 树的计数 Prufer序列
题目大意:给定一棵树中全部点的度数,求有多少种可能的树 Prufer序列.详细參考[HNOI2008]明明的烦恼 直接乘会爆long long,所以先把每一个数分解质因数.把质因数的次数相加相减.然后 ...
- BZOJ 1005 明明的烦恼(prufer序列+高精度)
有一种东西叫树的prufer序列,一个树的与一个prufer序列是一一对应的关系. 设有m个度数确定的点,这些点的度为dee[i],那么每个点在prufer序列中出现了dee[i]-1次. 由排列组合 ...
- BZOJ 1005 明明的烦恼 Prufer序列+组合数学+高精度
题目大意:给定一棵n个节点的树的节点的度数.当中一些度数无限制,求能够生成多少种树 Prufer序列 把一棵树进行下面操作: 1.找到编号最小的叶节点.删除这个节点,然后与这个叶节点相连的点计入序列 ...
- BZOJ 1005 prufer序列
给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? 第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di ...
- bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&&生成树计数
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2248 Solved: 898[Submit][Statu ...
随机推荐
- 左 or 右
背景: 掌握的知识:C++.MFC.设计模式.STL,熟悉windows网络编程,了解COM组件但是不精. 近期辞职找工作,发现windows下的C++开发职位很少.linux和移动端开发职位多,但是 ...
- .net环境下ckeditor与ckfinder中文文件链接乱码的问题
.net环境下ckeditor与ckfinder中文文件链接乱码的问题 将ckfinder.js中的getUrl:function(){return this.folder.getUrl()+enco ...
- Qt报表控件NCReport教程:报表创建示例
NCReport是 一款10多年时间的老牌报表控件,最初是在2002年时作为qt3的应用程序的一个联合项目,后来就成为了一个独立的GPL项目.现在的NCReport 是一款轻量级.快速.多平台.简单易 ...
- innodb数据结构
Jeremy Cole on InnoDB architecture : Efficiently traversing InnoDB B+Trees with the page directory ...
- CSS 笔记三(Tables/Box Model/Outline)
CSS Tables border border: border-width border-style border-color|initial|inherit; border-width borde ...
- [转] ubuntu开启SSH服务
点击阅读原文 SSH分客户端openssh-client和openssh-server如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudo ...
- Java 基础知识 问答
1,Java为什么能跨平台运行?请简述原理. 因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一种“中间码”——字节码.然后不同的硬件平台上安装有不同的Java虚拟机(JVM),由J ...
- 深入浅出设计模式——建造者模式(Builder Pattern)
模式动机无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.方向盘.发送机等各种部件.而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单 ...
- Deep Learning 15:RBM的学习
RBM是深度学习的核心,所以必须彻底清楚地理解RBM原理.推导及其训练方法 1.读学位论文“基于深度学习的人脸识别研究”: 对RBM.DBN的介绍比较详细,可以作为基础阅读,再去读英文论文. 2.RB ...
- android ViewGroup事件分发机制
1:事件分销过程 自定义一个LinearLayout,重写dispatchTouchEvent onInterceptTouchEvent onTouchEvent,定义一个按键重写dispathcT ...