zoukankan      html  css  js  c++  java
  • bzoj 5346: tree (其实是是某次雅礼集训的题)

       用prufer序列的公式直接dp,O(n^4)的算法简简单单就写出来了23333.

        按理说 O(n^4)是需要优化成O(n^3)才能过的,然鹅我也不知道我怎么过了23333

    (那就懒得优化了hhhhh)

    (后来翻了翻std,发现标算就是O(n^4)的。。。。迷)

    /*
        f[i][j] -> 已经选了i个节点,度数和为j 的∑( π1/(degree[i]-1)!)  
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int maxn=105,ha=1004535809;
    int f[maxn][maxn*2],n,d[maxn],jc[maxn],ni[maxn],M;
    
    inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
    inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
    
    inline int ksm(int x,int y){
    	int an=1;
    	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
    	return an;
    }
    
    inline void init(){
    	jc[0]=1;
    	for(int i=1;i<=100;i++) jc[i]=jc[i-1]*(ll)i%ha;
    	ni[100]=ksm(jc[100],ha-2);
    	for(int i=100;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
    }
    
    inline void solve(){
    	f[0][0]=1;
    	for(int i=1;i<=n;i++)
    	    for(int j=i-1;j>=0;j--)
    	        for(int k=M;k>=0;k--) if(f[j][k])
    	            for(int u=min(d[i],M-k);u;u--) ADD(f[j+1][k+u],f[j][k]*(ll)ni[u-1]%ha);
    }
    
    inline void calc(){
    	printf("%d ",n);
    	for(int i=2;i<=n;i++) printf("%d ",f[i][(i-1)<<1]*(ll)jc[i-2]%ha);
    	puts("");
    }
    
    int main(){
    	freopen("tree.in","r",stdin);
    	freopen("tree.out","w",stdout);
    	
    	init();
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",d+i),d[i]=min(d[i],n-1);
    	M=n*2-2,solve(),calc();
    	
    	return 0;
    }
    

      

  • 相关阅读:
    java 数组声明方法
    python 什么叫迭代
    Golang生成区间随机整数
    Golang字符串格式化
    Golang中map的三种声明方式和简单实现增删改查
    Golang实现二分查找法
    Golang实现冒泡排序法
    Golang切片的三种简单使用方式及区别
    Golang获取int数组里的最大值和下标
    Golang数组注意细节
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9084737.html
Copyright © 2011-2022 走看看