BZOJ 4011 HNOI2015 落忆枫音
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4011
题目很长,写得也很有诗意与浪漫色彩,让我们不禁感叹出题人是一个多么英俊潇洒的人。
所以题目大意就是:
给一个有向无环图,问加上一条我给定的边后,有多少个以1为根的树形图?n<=1e5,m<=2*1e5
原图无重边,加上的边可以为自环。
首先先来解决一个问题:
一个有向无环图的树形图有多少个呢?
相当于除了根节点以外,每个点随意取一个入度,为什么就一棵树呢?每个点选一个父亲,并且保证没有环,所以是一棵树。
好的,对于有向无环图就一定是这样的,那么若加入一条边<x,y>,
那么就可能再选择的过程中选出一个环[就是祖先的父亲是自己这种情况]。那么我们就需要删去这种情况。
首先要出现环,则必定包括了<x,y>这条边,剩下的部分是原图中y->x的一条路径,要求这条路径上的点必须选择一条路径使得构成一个环。而其它的点可以随意选。
设F(i)表示y->i上的点所成路径必须选择一条能构成环路径的方案数。
有初始值:

递推式:

相当于j可以选择延续所有从y走来的i的路径,但是要除以j原本可以选择的路径总数。
最后答案=所有方案[入度乘积] - F(x)。
听说ZZD去年就想出来了这题,不过因为不会打逆元而失之交臂[不然就是省队了?%%%]
为什么会有逆元?...额我好像忘记说方案数要取模了...
那么这题中为了加速运算,就用了一个O(n)递推求1...n的所有逆元的方法,我也算是普及一下吧?...

画图的时候没太注意大小写,不要太在意...
那么i的逆元可以由p mod i的逆元得知了,这显然是一个已知的数,所以每次递推都是O(1)的,边界:1的逆元=1。
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; inline int in(){
int x=;char ch=getchar();
while(ch>'' || ch<'') ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x;
} const int maxn=;
const int mod=1e9+;
typedef long long ll; struct Node{
int data,next;
}node[maxn<<]; #define now node[point].data
#define then node[point].next int n,m,ans,cnt,x,y;
int head[maxn],d[maxn],ld[maxn];
int f[maxn],stack[maxn],top;
int inv[maxn<<]; void init(){
inv[]=;
for(int i=;i<=m;i++)
inv[i]=(mod-(ll)inv[mod%i]*(mod/i)%mod)%mod;
} void add(int u,int v){
node[cnt].data=v;node[cnt].next=head[u];head[u]=cnt++;d[v]++;
} int power(int a,int k){
int ans=;
for(;k;k>>=){
if(k&) ans=(ll)ans*a%mod;
a=(ll)a*a%mod;
}
return ans;
} int main(){
#ifndef ONLINE_JUDGE
freopen("maple.in","r",stdin);
freopen("maple.out","w",stdout);
#endif int u,v; n=in(),m=in();
x=in(),y=in();
init();
for(int i=;i<=n;i++) head[i]=-;
for(int i=;i<=m;i++)
u=in(),v=in(),add(u,v);
d[y]++;
ans=;
for(int i=;i<=n;i++) ans=(ll)ans*d[i]%mod;
if(y==){ printf("%d",ans);return ;}
else f[y]=(ll)ans*inv[d[y]]%mod; d[y]--;
memcpy(ld,d,sizeof(d));
for(int i=;i<=n;i++) if(!d[i]) stack[++top]=i; while(top){
u=stack[top--];
for(int point=head[u];point!=-;point=then){
if(--d[now]==)
stack[++top]=now;
f[now]=(f[now]+(ll)f[u]*inv[ld[now]]%mod)%mod;
}
} ans=(ans-f[x]+mod)%mod;
printf("%d",ans);
return ;
}
BZOJ 4011 HNOI2015 落忆枫音的更多相关文章
- BZOJ 4011: [HNOI2015]落忆枫音( dp )
DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...
- BZOJ 4011: [HNOI2015]落忆枫音 计数 + 拓扑排序
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...
- BZOJ 4011 HNOI2015 落忆枫音 DAG上的dp(实际上重点在于分析)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题意概述:给出一张N点的DAG(从1可以到达所有的点),点1的入度为0.现在加一条原 ...
- 4011: [HNOI2015]落忆枫音
4011: [HNOI2015]落忆枫音 链接 分析: 原来是一个DAG,考虑如何构造树形图,显然可以给每个点找一个父节点,所以树形图的个数就是$\prod\limits_u deg[u]$. 那么加 ...
- 【BZOJ】4011: [HNOI2015]落忆枫音
题目链接:http://blog.csdn.net/popoqqq/article/details/45194103 写代码的时候也没有很清晰....具体看这里吧 #include<iostre ...
- bzoj4011[HNOI2015]落忆枫音 dp+容斥(?)
4011: [HNOI2015]落忆枫音 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1125 Solved: 603[Submit][Statu ...
- [HNOI2015]落忆枫音 解题报告
[HNOI2015]落忆枫音 设每个点入度是\(d_i\),如果不加边,答案是 \[ \prod_{i=2}^nd_i \] 意思是我们给每个点选一个父亲 然后我们加了一条边,最后如果还这么统计,那么 ...
- BZOJ4011: [HNOI2015]落忆枫音
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...
- [HNOI2015]落忆枫音
题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再 ...
随机推荐
- Leetcode 605.种花问题
种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表 ...
- SGX技术初探
一.SGX技术背景 1.1 SGX技术定义 SGX全称Intel Software Guard Extensions,顾名思义,其是对因特尔体系(IA)的一个扩展,用于增强软件的安全性.这种方式并不是 ...
- 根据窗口尺寸onresize判断窗口的大小
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- vim 查找命令
/要查找的内容 自光标起始位置向下查找 ?要查找的内容 自光标起始位置向上查找
- [HEOI2016/TJOI2016][bzoj4555] 求和 [斯特林数+NTT]
题面 传送门 思路 首先,我们发现这个式子中大部分的项都和$j$有关(尤其是后面的$2^j\ast j!$),所以我们更换一下枚举方式,把这道题的枚举方式变成先$j$再$i$ $f(n)=\sum_{ ...
- Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理
转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava E ...
- python安装matplotlib
linux安装 方法: 首先matplotlib是需要numpy先行包支持的,这里,我已经安装了numpy,下面安装matplotlib. matplot需要一些其他软件支持 (1)这时需要安装fre ...
- Repeater的使用及其鼠标特效,行链接的使用
原文发布时间为:2009-04-22 -- 来源于本人的百度文章 [由搬家工具导入] <asp:Repeater ID="rpt" runat="server&qu ...
- java网络编程学习笔记(一)
1.进程之间的通信 进程是指运行中的程序,进程的任务就是执行程序中的代码. 存在计算机网络上的两个进程只需要关注它们通信的具体内容,而不需关注消息在网络上传输的具体细节. 2.计算机网络的概念 Int ...
- Linux signal那些事儿【转】
转自:http://blog.chinaunix.net/uid-24774106-id-4061386.html Linux编程,信号是一个让人爱恨交加又不得不提的一个领域.最近我集中学习了Linu ...