bzoj1005: [HNOI2008]明明的烦恼
2016-02-11 23:04
309 查看
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1005
题意:中文题。。。
分析:prufer序列的应用,因为题目已经限制了一些节点的度,那么我们只要在prufer序列里取出x[i]-1个位置给它即可,若prufer序列中还有sum个位置没有被分配节点编号,那么就是那没有度数限制的g个节点任意去即g^sum中方案。那么前面的组合数学*g^sum就是答案啦。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<math.h> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=1020; const int MAX=151; const int MOD1=100000007; const int MOD2=100000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=9999991; const ll INF=10000000010; typedef unsigned long long ull; int a ,bo ,p [7],q [7]; void deal() { int i,j,w,k=0,n=1010; memset(bo,0,sizeof(bo)); bo[1]=1; for (i=2;i<=n;i++) { if (!bo[i]) a[++k]=i; for (j=1;j<=k;j++) { if (a[j]*i>n) break ; bo[a[j]*i]=1; if (i%a[j]==0) break ; } } memset(p,0,sizeof(p)); for (i=1;i<=k;i++) { w=a[i]; while (w<=n) { p[w][0]++;p[w][p[w][0]]=a[i];w+=a[i]; } } memset(q,0,sizeof(q)); for (i=1;i<=n;i++) { w=i; for (j=1;j<=p[i][0];j++) { while (w%p[i][j]==0) { q[i][j]++;w/=p[i][j]; } } } } int x ,ans[N*100],num ; void add(int x) { for (int i=1;i<=p[x][0];i++) num[p[x][i]]+=q[x][i]; } void sub(int x) { for (int i=1;i<=p[x][0];i++) num[p[x][i]]-=q[x][i]; } int main() { int i,j,k,g,n,flag=0,sum; scanf("%d", &n); deal();sum=n-2;g=0; for (i=1;i<=n;i++) { scanf("%d", &x[i]); if ((x[i]<1&&x[i]!=-1)||(x[i]>=n)) flag=1; if (x[i]!=-1) sum-=x[i]-1; else g++; } if (flag||sum<0||(g==0&&sum>0)) { printf("0\n");return 0; } memset(ans,0,sizeof(ans)); ans[0]=ans[1]=1; for (i=1;i<=sum;i++) { for (j=1;j<=ans[0];j++) ans[j]*=g; for (j=1;j<ans[0];j++) { ans[j+1]+=ans[j]/10;ans[j]%=10; } while (ans[ans[0]]>9) { ans[ans[0]+1]=ans[ans[0]]/10;ans[ans[0]]%=10;ans[0]++; } } memset(num,0,sizeof(num)); for (i=1;i<=n-2;i++) add(i); for (i=1;i<=sum;i++) sub(i); for (i=1;i<=n;i++) if (x[i]>1) { for (j=1;j<x[i];j++) sub(j); } for (i=1;i<=1000;i++) if (num[i]) { for (j=1;j<=num[i];j++) { for (k=1;k<=ans[0];k++) ans[k]*=i; for (k=1;k<ans[0];k++) { ans[k+1]+=ans[k]/10;ans[k]%=10; } while (ans[ans[0]]>9) { ans[ans[0]+1]=ans[ans[0]]/10;ans[ans[0]]%=10;ans[0]++; } } } for (i=ans[0];i>0;i--) printf("%d", ans[i]);printf("\n"); return 0; } /* 3 1 -1 -1 4 -1 -1 -1 2 */
相关文章推荐
- 基于SDP的提议/应答(offer/answer)模型简介
- javascript笔记7-事件
- 【Codeforces 282E】Sausage Maximization 中文题意&题解&代码(C++)
- Linux文件和目录的读、写、执行权限总结
- Atitit..net clr il指令集 以及指令分类 与指令详细说明
- 112. Path Sum LeetCode
- 9.数据结构之二叉树
- Atitit..net clr il指令集 以及指令分类 与指令详细说明
- Atitit..net clr il指令集 以及指令分类 与指令详细说明
- HDU 2126(01背包扩展,记录方案数)
- java中的构造方法
- POJ 3237 Tree 树链剖分
- 第22讲-控制结构与流程图-练习
- Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
- Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
- Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
- Atitit.跨语言反射api 兼容性提升与增强 java c#。Net php js
- Atitit.跨语言反射api 兼容性提升与增强 java c#。Net php js
- Atitit.跨语言反射api 兼容性提升与增强 java c#。Net php js
- iOS之小功能模块--彩虹动画进度条学习和自主封装改进