https://scut.online/p/482

没听说过这个东西。

洛谷也有这个,所以还是要去接触一些奇奇怪怪的知识才行。

https://www.luogu.org/problem/P2290

画了一个表。

1个点:

F[1]=1

2个点:

F[1]=1

F[2]=1

3个点:

F[1]=2/3

F[2]=1/3

F[3]=0

4个点:

F[1]=9/16

F[2]=4/16

F[3]=1/16

F[4]=0

没发现有什么规律,可能是真的要画到5才可以?


Prufer序列,用于对同一形态的无根树映射到序列。用来解决只跟度数有关的树的问题。

1.找度数为1的,且编号最小的点,把它的父亲加入Prufer序列,且把它删除。

然后会得到一个n-2个点的序列,其中出现元素的次数就是他的度数-1。

从Prufer恢复树:

2.取出Prufer的第一个节点x,把不在Prufer里的最小元素y,在x-y之间连边。

性质:

1.prufer序列与无根树一一对应。

2.度数为d_i的节点会在prufer序列中出现d_i-1次。

3.一个n个节点的完全图的生成树个数为n{n-2}。因为对于一个n个点的无根树,它的prufer序列长为n−2,而每个位置有n种可能性,因此可能的prufer序列有n{n-2}种。很显然每一种无根树唯一对应完全图的一个生成树。

4.对于给定度数序列为d_i的一棵无根树共有 \(\frac{(n-2)!}{\prod_{i=1}^n(d_i-1)!}\) 种情况。由上面的性质可以知道,度数为d_i的节点会在prufer序列中出现d_i-1次。则就是要求出d_i-1个i的全排列个数。而上面那个式子就是可重全排列公式。(即全排列个数除以重复元素内部的全排列个数)


回到这一题,每种生成树对应一个Prufer序列,那么总共肯定是n{n-2}种生成树,其中F[1]肯定是不选1,那么就是(n-1){n-2},以此类推。


众所周知,幂函数是完全积性的。把它移动一下就可以了。


还卡内存,真的毒瘤。开多一个F数组拿来复制都不行。

事实上不需要这么强迫症,写个函数映射过去,或者直接在答案里面映射过去就可以了。

试试证明bitset在单个访问的时候对时间的浪费程度比bool大。

然而因为MOD是一个1e9+7,所以不会有任何比它小的数的幂次会MOD它为0,可以直接用G[i]来判断。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int MOD = 1e9 + 7; int qpow(ll x, int n) {
ll res = 1;
while(n) {
if(n & 1)
res = res * x % MOD;
x = x * x % MOD;
n >>= 1;
}
return res;
} const int MAXN = 5e7 + 500; int G[MAXN];
int p[3100000], ptop;
//int pk[MAXN]
bool np[MAXN];
int N, L, R; void sieve(int n) {
G[0] = 0;
G[1] = 1;
//pk[1]=1;
np[1] = 1;
for(int i = 2; i <= n; i++) {
if(!np[i]) {
p[++ptop] = i;
//pk[i] = i;
G[i] = qpow(i, N - 2);
}
for(int j = 1, t; j <= ptop && (t = i * p[j]) <= n; j++) {
np[t] = 1;
if(i % p[j]) {
//pk[t] = p[j];
G[t] = 1ll * G[i] * G[p[j]] % MOD;
} else {
//pk[t] = pk[i] * p[j];
//下面是积性
/*if(pk[t] == t) {
G[t] = qpow(N - t, N - 2);
} else {
G[t] = 1ll * G[pk[t]] * G[t / pk[t]] % MOD;
}*/
//其实G[i]是完全积性
G[t] = 1ll * G[i] * G[p[j]] % MOD;
break;
}
}
}
//printf("%d\n",ptop);
/*for(int i = 1; i <= N; ++i) {
F[i] = G[N - i];
//printf("F[%d]=%d\n", i, F[i]);
}*/
/*reverse(G, G + N + 1);
for(int i = 1; i <= N; ++i) {
G[i] += G[i - 1];
if(G[i]>=MOD)
G[i]-=MOD;
//printf("F[%d]=%d\n", i, F[i]);
}*/
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
while(~scanf("%d%d%d", &N, &L, &R)) {
if(N <= 2) {
printf("%d\n", R - L + 1);
continue;
}
sieve(N);
int ANS = 0;
for(int i = N - R; i <= N - L; ++i) {
ANS += G[i];
if(ANS >= MOD)
ANS -= MOD;
}
printf("%d\n", 1ll * ANS * qpow(qpow(N, N - 2), MOD - 2) % MOD);
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int MOD = 1e9 + 7; int qpow(ll x, int n) {
ll res = 1;
while(n) {
if(n & 1)
res = res * x % MOD;
x = x * x % MOD;
n >>= 1;
}
return res;
} const int MAXN = 5e7 + 5; int G[MAXN];
int p[3100000], ptop;
int N, L, R; void sieve(int n) {
G[0] = 0;
G[1] = 1;
for(int i = 2; i <= n; i++) {
if(!G[i]) {
p[++ptop] = i;
G[i] = qpow(i, N - 2);
}
for(int j = 1, t; j <= ptop && (t = i * p[j]) <= n; j++) {
G[t] = 1ll * G[i] * G[p[j]] % MOD;
if(!(i % p[j]))
break;
}
}
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
while(~scanf("%d%d%d", &N, &L, &R)) {
if(N <= 2) {
printf("%d\n", R - L + 1);
continue;
}
sieve(N);
int ANS = 0;
for(int i = N - R; i <= N - L; ++i) {
ANS += G[i];
if(ANS >= MOD)
ANS -= MOD;
}
printf("%d\n", 1ll * ANS * qpow(qpow(N, N - 2), MOD - 2) % MOD);
}
return 0;
}

SCUT - 482 - 生成树上的点 - Prufer的更多相关文章

  1. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

  2. prufer编码

    看51nod的一场比赛,发现不会大家都A的一道题,有关prufer的 我去年4月就埋下prufer这个坑,一直没解决 prufer编码是什么 对于一棵无根树的生成的序列,prufer序列可以和无根树一 ...

  3. 图论:Prufer编码

    BZOJ1211:使用prufer编码解决限定结点度数的树的计数问题 首先学习一下prufer编码是干什么用的 prufer编码可以与无根树形成一一对应的关系 一种无根树就对应了一种prufer编码 ...

  4. CF E2 - Daleks' Invasion (medium) (LCA求两点树上路径上的最大边权)

    http://codeforces.com/contest/1184/problem/E2 题意:给出一副图,首先求出这幅图的最小生成树 , 然后修改这幅图上不属于最小生成树的边权,使得修改后的图在求 ...

  5. Solution -「树上杂题?」专练

    主要是记录思路,不要被刚开始错误方向带偏了 www 「CF1110F」Nearest Leaf 特殊性质:先序遍历即为 \(1 \to n\),可得出:叶子节点编号递增或可在不改变树形态的基础上调整为 ...

  6. Codeforces 611H - New Year and Forgotten Tree(二分图多重匹配)

    Codeforces 题目传送门 & 洛谷题目传送门 首先我们将所有十进制下位数相同的点看作一种颜色,这样题目转化为,给定 \(m\le 6\) 种颜色.每种颜色的点的个数 \(b_i\) 以 ...

  7. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  8. HDU 4081Qin Shi Huang's National Road System(次小生成树)

    题目大意: 有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点.秦始皇希望这所有n-1条路长度之和最短.然后徐福突然有冒出来,说是他有魔法,可以不用人力.财力就变 ...

  9. CF576E

    *在#里发他一直WA这道CF题,然后我就去看了看,感觉还挺有趣的,那我就在这里整理一下我的思路..毕竟一边听歌.. 题意: 给个图,每条边初始无色,每次给一个询问(e,c)表示把e涂成颜色c,如果此时 ...

随机推荐

  1. AngularJS的目录结构

    templates/ _login.html _feed.html app/ app.js controllers/ LoginController.js FeedController.js dire ...

  2. (56)Linux驱动开发之二

                                                                                             内核基础   1.li ...

  3. [CF1101F]Trucks and Cities:分治优化决策单调性

    分析 好像是有一个叫这个名字的算法,链接. 令\(f[i][j][k]\)表示一辆每公里耗油量为\(1\)的货车从\(i\)到\(j\)中途加\(k\)次油最小的油箱容量.枚举所有的起点和中途加油的次 ...

  4. Spring Cloud Config教程(五)客户端使用

    要在应用程序中使用这些功能,只需将其构建为依赖于spring-cloud-config-client的Spring引导应用程序(例如,查看配置客户端或示例应用程序的测试用例).添加依赖关系的最方便的方 ...

  5. 通过ecplise导入mysql的jar包时,右键找不到build path问题

    当我们执行java连接数据库程序的时候,我们需要再我们的项目里导入mysql的jar包,这时,我们需要右键->build path进行导入,但是有时候我们右键的时候并没有出现build path ...

  6. Run nginx from Docker in Windows

    1.首先, 使用 docker run hello-world 命令 确认 docker 在本地安装成功,若成功应如下所示(此处使用的是 Docker Toolbox 在Windows上安装Docke ...

  7. 关于kafka在windows上的安装、运行

    一.安装kafka    下载地址:http://kafka.apache.org/downloads 要下载Binary downloads这个类型,不要下载源文件,这种方便使用.下载后,解压放在D ...

  8. Js自定义数组map之bigmap

    /** * like map,but prev,curr,next and index will be given * @param {Function} cb Callback,the parame ...

  9. scss 用法 及 es6 用法讲解

    scss 用法的准备工作,下载 考拉 编译工具 且目录的名字一定不能出现中文,哪里都不能出现中文,否则就会报错 es6 用法 let 和 const  let  声明变量的方式 在 {} 代码块里面才 ...

  10. 1450:【例 3】Knight Moves

    1450:[例 3]Knight Moves  题解 这道题可以用双向宽度搜索优化(总介绍在  BFS ) 给定了起始状态和结束状态,求最少步数,显然是用BFS,为了节省时间,选择双向BFS. 双向B ...