组合计数的一道好题。什么非主流题目

题目背景

(背景冗长请到题目页面查看)

题目描述

不妨假设枫叶上有 \(n​\) 个穴位,穴位的编号为 \(1\sim n​\)。有若干条有向的脉络连接着这些穴位。穴位和脉络组成一个有向无环图——称之为脉络图(例如图 1),穴位的编号使得穴位 \(1​\) 没有从其他穴位连向它的脉络,即穴位 1 只有连出去的脉络;由上面的故事可知,这个有向无环图存在一个树形子图,它是以穴位 \(1​\) 为根的包含全部 \(n​\) 个穴位的一棵树——称之为脉络树(例如图 2 和图 3 给出的树都是图 1 给出的脉络图的子图);值得注意的是,脉络图中的脉络树方案可能有多种可能性,例如图 2 和图 3 就是图 1 给出的脉络图的两个脉络树方案。

脉络树的形式化定义为:以穴位 \(r\) 为根的脉络树由枫叶上全部 \(n\) 个穴位以及 \(n-1\) 条脉络组成,脉络树里没有环,亦不存在从一个穴位连向自身的脉络,且对于枫叶上的每个穴位 \(s\),都存在一条唯一的包含于脉络树内的脉络路径,使得从穴位 \(r\) 出发沿着这条路径可以到达穴位 \(s\)。

现在向脉络图添加一条与已有脉络不同的脉络(注意:连接 \(2\) 个穴位但方向不同的脉络是不同的脉络,例如从穴位 \(3\) 到 \(4\) 的脉络与从 \(4\) 到 \(3\) 的脉络是不同的脉络,因此,图 1 中不能添加从 \(3\) 到 \(4\) 的脉络,但可添加从 \(4\) 到 \(3\) 的脉络),这条新脉络可以是从一个穴位连向自身的(例如,图 1 中可添加从 \(4\) 到 \(4\) 的脉络)。原脉络图添加这条新脉络后得到的新脉络图可能会出现脉络构成的环。

请你求出添加了这一条脉络之后的新脉络图的以穴位 \(1\) 为根的脉络树方案数。

由于方案可能有太多太多,请输出方案数对 \(1000000007\) 取模得到的结果。

输入格式

输入文件的第一行包含四个整数 \(n\)、\(m\)、\(x\) 和 \(y\),依次代表枫叶上的穴位数、脉络数,以及要添加的脉络是从穴位 \(x\) 连向穴位 \(y\) 的。

接下来 \(m\) 行,每行两个整数,由空格隔开,代表一条脉络。第 \(i\) 行的两个整数为 \(u_i\) 和 \(v_i\),代表第 \(i\) 条脉络是从穴位 \(u_i\) 连向穴位 \(v_i\) 的。

输出格式

输出一行,为添加了从穴位 \(x\) 连向穴位 \(y\) 的脉络后,枫叶上以穴位 \(1\) 为根的脉络树的方案数对 \(1000000007\) 取模得到的结果。

输入输出样例

输入样例:

4 4 4 3
1 2
1 3
2 4
3 2

输出样例:

3

数据范围与约定

对于所有测试数据,\(1\leq n\leq 100000, \ n-1 \leq m \leq \min \left(200000, \frac{n(n - 1)}{2}\right), \ 1 \leq x, y, u_i, v_i \leq n​\)。

题解:

首先需要找出一个不需要拓扑排序就能解决不加边时的脉络树数量的方法。

对于每个点 \(u(u\ge 2)\) ,假定它的入度为 \(d_i\) ,则它有 \(d_i\) 个父亲可供选择。我们只需要从上往下看,就可以发现每一层都是互相独立的,因此加边之前脉络树的数量为
\[ \prod_{i=2}^nd_i \]
此时考虑加边。正常情况下按上面的方式计数,边数为 \(n-1\) 的图的总数 \(sum\) 为
\[ sum=\prod_{i=2}^n\left(d_i+[i=y]\right) \]
但是实际上不是所有 \(sum\) 种方案都符合题意,由于每个点选择父亲是自由从入边选的,因此可能存在环,此时就不满足”脉络树“的定义了,而且图/树也没有明显分层。

我们考虑所有的 \(sum​\) 种方案,从中减掉包含环的那些方案。由于我们加入的边是 \(\left<x,y\right>​\),所以一定是与路径 \(y\to x​\) 成环。因此我们只需要排除那些包含 \(y\to x\) 的路径的边数为 \(n-1​\) 的图就可以了。

注意由于加了新边之后的图只有一个环,因此 \(n-1​\) 条边的图也最多只有一个环。

话再说回来,包含 \(y\to x​\) 的路径的图我们可以认为这条路径上的所有点(包括 \(x,y​\))都被钦定了一个父亲(其中 \(x​\) 的父亲认为是 \(y​\),因为要成环)。假设用 \(S=\left\{a_i\right\}​\) 表示这条路径,那么包含 \(y\to x​\) 的图种类数就是 \(\prod_{i\notin S}d_i​\)。

而最终的答案就是 \(sum-\sum_{S:y\to x}\prod_{i\notin S}d_i​\)。

此时考虑如何求出所有的 \(y\to x\)。可以建立原图的反向边,跑拓扑排序。设定状态 \(f_k\) 表示 \(\sum_{S:k\to x}\prod_{i\notin S}d_i\),每次从原图的边 \(\left<u,v\right>\) 转移时,即钦定了 \(v\) 的入边,所以状态转移方程为
\[ f_u=\sum_{\left<u,v\right>\in E}\frac{f_v}{d_v} \]
由于我们还要钦定 \(x\) 的入边是 \(y\),因此最终的答案是
\[ ans=sum-\frac{f_x}{d_x} \]
时间复杂度为 \(O(n)\) 或 \(O(n\log n)\) (在线求逆元)

Code:

#include<cstdio>
#include<cstring>
#define p 1000000007
int Plus(int x,int y)
{return (x+y>=p)?(x+y-p):(x+y);}
int Mul(int x,int y)
{return 1ll*x*y%p;}
struct edge
{int n,nxt;edge(int n,int nxt){this->n=n;this->nxt=nxt;}edge(){}
}e[200000];
int head[100100],ecnt=-1;
void add(int from,int to)
{e[++ecnt]=edge(to,head[from]);head[from]=ecnt;
}
int d[100100],in[100100];
//d表示真实入度 in表示拓扑排序中的入度
int q[100100],l=0,r=0;
int f[100100],inv[100100];
int main()
{memset(head,-1,sizeof(head));inv[1]=1;for(int i=2;i<=100000;++i)inv[i]=Mul(p-p/i,inv[p%i]);int n,m,x,y,u,v;scanf("%d%d%d%d",&n,&m,&x,&y);for(int i=1;i<=m;++i){scanf("%d%d",&u,&v);add(v,u);++in[u];++d[v];}f[x]=1;int sum=1;for(int i=2;i<=n;++i){if(!in[i])q[++r]=i;f[x]=Mul(f[x],d[i]);sum=Mul(sum,d[i]+(i==y));}if(y==1){printf("%d\n",sum);return 0;}while(l<r){int k=q[++l];for(int i=head[k];~i;i=e[i].nxt){--in[e[i].n];f[e[i].n]=Plus(f[e[i].n],Mul(f[k],inv[d[k]]));if(!in[e[i].n])q[++r]=e[i].n;}}printf("%d\n",Plus(sum,p-Mul(f[y],inv[d[y]])));return 0;
}

转载于:https://www.cnblogs.com/wjyyy/p/lg3244.html

洛谷 P3244 / loj 2115 [HNOI2015] 落忆枫音 题解【拓扑排序】【组合】【逆元】相关推荐

  1. 【题解】 [HNOI2015]落忆枫音 (拓扑排序+dp+容斥原理)

    原题戳我 Solution: (部分复制Navi_Aswon博客) 解释博客中的两个小地方: \[\sum_{\left(S是G中y→x的一条路径的点集\right))}\prod_{2≤j≤n,(j ...

  2. BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)

    Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题.  「相信吧.不然我们是什么,一团肉吗?要不是有灵魂--我们也 ...

  3. P3244 [HNOI2015]落忆枫音(DAG上的动态规划问题,朱刘定理,乘法逆元)

    P3244 [HNOI2015]落忆枫音 样例太坑了!竟然和题目描述给的图不一样! 题目描述 给定一张有向无环图,这张图满足一个性质:以点1为根节点,保证至少有一棵有向树,连接所有的节点. 现在向这张 ...

  4. luogu P3244 [HNOI2015]落忆枫音

    传送门 md这题和矩阵树定理没半毛钱关系qwq 首先先不考虑有环,一个\(DAG\)个外向树个数为\(\prod_{i=2}^{n}idg_i(\)就是\(indegree_i)\),因为外向树每个点 ...

  5. [HNOI2015]落忆枫音

    题目描述 不妨假设枫叶上有 n个穴位,穴位的编号为 1 ~  n.有若干条有向的脉络连接 着这些穴位.穴位和脉络组成一个有向无环图--称之为脉络图(例如图 1),穴 位的编号使得穴位 1 没有从其他穴 ...

  6. luogu3244 bzoj4011 HNOI2015 落忆枫音

    这道题目题面真长,废话一堆. 另外:这大概是我第一道独立做出来的HNOI2011年以后的题目了吧.像我水平这么差的都能做出来,dalao您不妨试一下自己想想? 题目大意:给一个DAG,其中1号点没有入 ...

  7. [HNOI2015] 落忆枫音

    题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再 ...

  8. Bzoj4011 [HNOI2015]落忆枫音

    Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 983  Solved: 533 Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫 ...

  9. BZOJ 4011 HNOI2015 落忆枫音

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题目很长,写得也很有诗意与浪漫色彩,让我们不禁感叹出题人是一个多么英俊潇洒的人. 所 ...

最新文章

  1. C# 写Windows服务
  2. 实验四:Telnet远程登录服务器的安装、管理及Telnet客户端的应用
  3. virtio-blk简介
  4. 20145226《信息安全系统设计基础》第1周学习总结
  5. 关于C语言的问卷调查
  6. 项目范围管理:项目范围控制
  7. DCMTK:dicom标签的基础类
  8. 逆向了一下hh.exe
  9. Android 视频播放器,VideoView播放视频
  10. 生成一个文件 保存在指定的文件夹中 思路 python
  11. excel文件无法打印提示内存不足_U盘拷贝文件提示目标文件过大无法复制怎么解决...
  12. JavaScript PopUp生成器
  13. MySQL48道经典基础面试题(包含各个方面)
  14. 树莓派 4b 可执行文件 无法双击运行_树莓派01 - 树莓派系统安装
  15. mysql把字段拆成两个_MySQL数据库中,将一个字段的值分割成多条数据显示
  16. matlab中如何画柱状图,如何在用Matlab画柱状图
  17. ArcGIS与GIS知识:ARCGIS中坐标转换及地理坐标、投影坐标的定义以及投影分度带的划分
  18. 苹果推送证书不受信任解决办法2022年
  19. 打开服务器网页要5秒,网页优化技巧 如何把网页加载时间控制在1.5秒以内
  20. python列表逆序

热门文章

  1. android native.js,Android Native与JS通信互调
  2. './mysql-bin.index' not found (Errcode: 13) 的解决方法
  3. 使用composer下载依赖包下载失败的解决方法
  4. chart.js绘制精美的数据化图形--入门示例
  5. PyRun_SimpleFile()崩溃问题
  6. 判断一个无符号整数是不是2的幂
  7. Linux 统计文件行数,字节数。
  8. VMware 常见使用问题梳理
  9. [react] 请说说什么是useRef?
  10. Taro+react开发(70):flex布局