51Nod 1806 wangyurzee的树

1806 wangyurzee的树

链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1806

想法:因为$m \le 17$,所以用容斥统计一下。即限定一些$u_i$的度数为$d_i$,然后变成Prufer统计带标号树的计数。

#include< cstdio >

#define FILE(F) freopen(F".in","r",stdin),freopen(F".out","w",stdout)
#define gec getchar
#define DEBUG fprintf(stderr,"Passing [%s] in Line (%d)\n",__FUNCTION__,__LINE__);

typedef long long ll;
template
inline void read(T&x)
{
	x=0;bool f=0;char c=gec();
	for(;c<‘0‘||c>‘9‘;c=gec())f|=(c==‘-‘);
	for(;c>=‘0‘&&c<=‘9‘;c=gec())x=x*10+c-‘0‘;
	x=f?-x:x;
}

const int MAXN(1e6+10),S(1<<17),MP(1000000007);
int inv[MAXN],fac[MAXN],ok[20];
void Deal_Fac(int n)
{
	fac[0]=inv[0]=inv[1]=1;
	for(int i=1;i<=n;i++)fac[i]=(ll)fac[i-1]*i%MP;
	for(int i=2;i<=n;i++)inv[i]=(MP-MP/i)*(ll)inv[MP%i]%MP;
	for(int i=2;i<=n;i++)inv[i]=(ll)inv[i]*inv[i-1]%MP;
}
int A(int n,int m)
{return n>=m?(ll)fac[n]*inv[n-m]%MP:0;}
int C(int n,int m)
{return n>=m?(ll)fac[n]*inv[m]%MP*(ll)inv[n-m]%MP:0;}
int power(int a,int b)
{
	int t=1;
	for(;b;b>>=1){if(b&1)t=(ll)t*a%MP;a=(ll)a*a%MP;}
	return t;
}
int n,m,d[20],u[20],Ans;
int main()
{
#ifndef ONLINE_JUDGE
	FILE("C");
#endif
	Deal_Fac(1e6); read(n);read(m);
	for(int i=0;i<m;i++)read(u[i]),read(d[i]),u[i]--;
	for(int i=0,tmp,sum,cnt,cont;i<1<<m;i++)
	{
		tmp=1;sum=0;cnt=0;cont=0;
		for(int j=0;j<m;j++)
		if(i&(1<<j))
		{
			if(ok[u[j]]==i){cont=1;break;} ok[u[j]]=i;
			tmp=(ll)tmp*C(n-2-sum,d[j]-1)%MP;sum+=d[j]-1;cnt++;
		}
		if(sum>n-2||cont)continue;//巧了,不存在。
		tmp=(ll)tmp*power(n-cnt,n-2-sum)%MP;
		if(cnt&1)Ans-=tmp;else Ans+=tmp;
		Ans%=MP;
	}
	if(n==1&&m==0)Ans=1;
	Ans+=Ans<0?MP:0;
	printf("%d\n",Ans);
	return 0;
}
				
时间: 2024-10-12 17:10:28

51Nod 1806 wangyurzee的树的相关文章

51nod 1272 思维/线段树

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272 1272 最大距离 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对.每个元素和自己也可以组成一对.例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标):

51nod 配对(求树的重心)

传送门:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 给出一棵n个点的树,将这n个点两两配对,求所有可行的方案中配对两点间的距离的总和最大为多少. Input 一个数n(1<=n<=100,000,n保证为偶数) 接下来n-1行每行三个数x,y,z表示有一条长度为z的边连接x和y(0<=z<=1,000,000,000) Output 一个数表示答案 Input示例 6 1 2 1 1 3 1

51Nod 1737 配对(树的重心)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 题意: 思路: 树的重心. 树的重心就是其所以子树的最大的子树结点数最少,删除这个点后最大连通块的结点数最小,也就说各个连通块尽量平衡. 这道题的话就是先求一个重心,然后求各个点到重心的距离之和. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #inclu

51Nod 1272最大距离 (树状数组维护前缀最小值)

题目链接 最大距离 其实主流解法应该是单调栈--我用了树状数组. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i) 6 7 const int N = 100010; 8 9 struct node{ 10 int x, y; 11 friend bool operator < (const node &a, c

51Nod 1443 路径和树

还是一道很简单的基础题,就是一个最短路径树的类型题目 我们首先可以发现这棵树必定满足从1出发到其它点的距离都是原图中的最短路 换句话说,这棵树上的每一条边都是原图从1出发到其它点的最短路上的边 那么直接跑最短路,SPFA,不存在的?我只信DJ,然后记录那些边在最短路上 然后直接跑MST即可.是不是很经典的水题 然后我又莫名拿了Rank1(没办法天生自带小常数) CODE #include<cstdio> #include<cctype> #include<cstring>

51nod 1443 路径和树——最短路生成树

题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 不只是做一遍最短路.还要在可以选的边里选最短的才行. 以为是求一遍最短路,然后按边权对边排序,哪条边两边的dis正好吻合,就把该边的边权加到ans里,把两端加到并查集里. 但其实不对.因为忽略了方向.比如如果有多个点同样地可以更新一个点,算的时候可能这多个点都因为那个点而被合到了并查集里,但其实只能有一个被合进去. 其实只要松弛点的时候如果dis[v]==d

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假

51nod 1412 AVL树的种类(经典dp)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k]$表示i个结点,最大深度为k的形态数. 它的转移方程就是: dp[i][k] += dp[i - 1 - j][k - 1] * dp[j][k - 1] dp[i][k] += 2 * dp[i - 1 - j][k - 2] * dp[j][k - 1] j是右子树结点个数,如果除去根结点,是不

51nod 1287 线段树

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287 简单的线段树题目,直接写个二分查找大于等于x的最小位置就好了. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define inf 0x3f3f3f3f 4 #define LL long long 5 const int MAX=50005; 6 int A[MAX]; 7 struct SegTree