【题解】51nod 1806 wangyurzee的树
看这道题目懵逼了好久, \(m <= 17\) 一眼容斥,然而并没有想到怎么求出生成树的个数。然后灵光一闪——我不是学过一个叫Prüfer编码的东西嘛?!那就完美解决啦~
Prüfer编码就是将一棵无根树映射到一串编码上的编码方法,一棵 \(n\) 个节点的树与一个长度为 \(n - 2\) 的编码串一一对应。所以我们要求合法的 = 总数 \(n ^ {n - 2}\) - 不合法的方案数。不合法的方案数 = 至少有 \(1\) 个不合法 - 至少有 \(2\) 个不合法 + 至少有\(3\) 个不合法……有何求出至少有 \(k\) 个不合法的方案数呢?
我们可以首先搜索出这 \(k\) 个限制(复杂度约为 \(2^{17}\)),然后令这\(k\) 个限制的 \(sum = \sum d[i] - 1\),\(sum\) 即为这 \(k\) 个限制中所牵涉到的节点在数列中一共应该出现的次数。满足这个限制(每一个节点出现 \(d[i] - 1\) 次)的数列个数即为 \(\frac{sum!}{\prod (d[i] - 1)!}\)。又因为这 \(sum\) 个数可以出现在长度为 \(n - 2\) 的数列中的任何位置,所以 乘上\(C(n - 2, sum)\),剩下的 \(n - 2 - sum\) 个数则可以随便选择,有 \((n - k) ^ {n - sum - 2}\) 种方案。完美~
#include <bits/stdc++.h>
using namespace std;
#define maxn 2000000
#define int long long
#define mod 1000000007
int n, m, fac[maxn];
int cnt, tot = , Ans = , S[maxn];
bool mark[maxn], vis[maxn]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct node
{
int x, d;
}Q[maxn]; int Qpow(int x, int timer)
{
int base = ;
for(; timer; timer >>= , x = x * x % mod)
if(timer & ) base = base * x % mod;
return base;
} int C(int n, int m)
{
if(m > n) return ;
return fac[n] * Qpow(fac[m], mod - ) % mod * Qpow(fac[n - m], mod - ) % mod;
} void Search(int now, int last)
{
if(m - last + < now) return;
if(!now)
{
int tem = , sum = ;
for(int i = ; i <= cnt; i ++)
tem = tem * (fac[Q[S[i]].d - ]) % mod,
sum += Q[S[i]].d - ;
if(sum > n - ) return;
tem = Qpow(tem, mod - );
tem = tem * fac[sum] % mod * C(n - , sum) % mod * Qpow(n - cnt, n - sum - ) % mod;
if(cnt & ) Ans = (Ans - tem + mod) % mod;
else Ans = (Ans + tem) % mod;
return;
}
for(int i = last; i <= m; i ++)
{
if(vis[Q[i].x]) continue;
S[++ cnt] = i, vis[Q[i].x] = ; Search(now - , i + );
cnt --, vis[Q[i].x] = ;
}
} signed main()
{
n = read(), m = read();
for(int i = ; i <= m; i ++)
Q[i].x = read(), Q[i].d = read();
if(n - > ) Ans = Qpow(n, n - );
else
{
printf("1\n");
return ;
}
fac[] = ;
for(int i = ; i <= n; i ++) fac[i] = fac[i - ] * i % mod;
for(int i = ; i <= m; i ++) Search(i, );
printf("%lld\n", Ans);
return ;
}
【题解】51nod 1806 wangyurzee的树的更多相关文章
- 51nod 1806 wangyurzee的树
基准时间限制:1 秒 空间限制:131072 KB wangyurzee有n个各不相同的节点,编号从1到n.wangyurzee想在它们之间连n-1条边,从而使它们成为一棵树.可是wangyur ...
- 题解 P1276 校门外的树(增强版)
前言 本蒟蒻重学线段树,发现了这道题可以用线段树做. 虽然数据范围很小可以直接暴力,但由于在练习线段树所以打算用线段树写这道题. 本题解针对已经有线段树基础的巨佬,不懂线段树原理的话可以学习线段树后再 ...
- 51nod 1443 路径和树(最短路)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 1443 路径和树 题目来源: CodeForces ...
- 51nod 1443 路径和树(最短路树)
题目链接:路径和树 题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和. 题解:构造出最短路树,把存留下来的边权全部加起来.(跑dijkstra的时候松弛加上$ < $变成 ...
- 51nod 1681 公共祖先 | 树状数组
51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...
- 51Nod 1737 配对(树的重心)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 题意: 思路: 树的重心. 树的重心就是其所以子树的最大的子树结点 ...
- 51nod 1272 思维/线段树
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272 1272 最大距离 题目来源: Codility 基准时间限制:1 ...
- HH的项链题解(离线思想+链表+树状数组)
本人第一篇博客重磅推出!!! 希望各位朋友以后多多捧场也多给写意见(我个人喜欢把题解写得啰嗦一点,因为这样方便理解,各位巨佬勿喷) 来讲一道提高+/省选-的骚题:HH的项链(这个HH你理解成皇后呵呵哈 ...
- 51nod 1376【线段树维护区间最大值】
引自:wonter巨巨的博客 定义 dp[i] := 以数字 i(不是下标 i)为结尾的最长上升长度 然后用线段树维护 dp[i]: 每个节点维护 2 个信息,一个是当前区间的最大上升长度,一个是最大 ...
随机推荐
- GitHub 配置指南
Git和GitHub的区别 GitHub术语解析 配置使用 注册GitHub帐号 创建Git 创建库 复制库 社交化 Git和GitHub的区别 Git是一个分布式的版本控制系统,与SVN类似:最初由 ...
- iOS UIWebView加载时添加进度条01
标注:此框架仅适合UIWebView 对iOS8后新出的WKWebView不适用,当然,你可以尝试修改框架里的几个代理方法. 框架是:NJKWebViewProgress 导入头文件 #import ...
- JMeter性能测试的基础知识和个人理解
JMeter性能测试的基础知识和个人理解 1. JMeter的简介 JMeter是Apache组织开发的开源项目,设计之初是用于做性能测试的,同时它在实现对各种接口的调用方面做的比较成熟,因此,常 ...
- 「日常训练」Alternative Thinking(Codeforces Round #334 Div.2 C)
题意与分析 (CodeForces - 603A) 这题真的做的我头疼的不得了,各种构造样例去分析性质... 题意是这样的:给出01字符串.可以在这个字符串中选择一个起点和一个终点使得这个连续区间内所 ...
- 洪水!(Flooded! ACM/ICPC World Final 1999,UVa815)
题目描述:竞赛入门经典的习题4-10 解题思路:1.把各个网格想象成一个数组 2.排序 3.雨水总体积去铺满 //太懒了只写了求海拔 #include <stdio.h> #define ...
- 【机器学习】线性回归sklearn实现
线性回归原理介绍 线性回归python实现 线性回归sklearn实现 这里使用sklearn框架实现线性回归.使用框架更方便,可以少写很多代码. 写了三个例子,分别是单变量的.双变量的和多变量的.单 ...
- 如何在etherscan提交代币官方信息
https://ethlinkersupport.zendesk.com/hc/zh-cn/articles/360001334992-%E5%A6%82%E4%BD%95%E5%9C%A8ether ...
- jQuery实现checkbox(复选框)选中、全选反选代码
谁都知道 在html 如果一个复选框被选中 是 checked="checked". 但是我们如果用jquery alert($("#id").attr(&qu ...
- OpenCV学习4-----K-Nearest Neighbors(KNN)demo
最近用到KNN方法,学习一下OpenCV给出的demo. demo大意是随机生成两团二维空间中的点,然后在500*500的二维空间平面上,计算每一个点属于哪一个类,然后用红色和绿色显示出来每一个点 如 ...
- css3美化radio样式
.magic-radio{ position: absolute; display: none; } .magic-radio + label { position: relative; displa ...