洛谷3244 落忆枫音 (拓扑图dp+式子)
题目大意就是 给你一个DAG
然后添加一条边\(x->y\) ,询问以1为根的生成树的个数
QWQ
首先假设没有添加的边
答案就应该是
\]
QWQ就相当于每个点选择一个父亲。
那么加入一条边,我们会有一些不合法的情况,那就是包含一条\(y->x\)路径,剩下随便选的方案数。假设全集是\(C\),然后路径上的点的集合是\(S\),那我们实际上求的就是$$\frac{F(C)}{F(S)}$$
其中\(F(S)\)表示\(S\)集合中所有点的入度的乘积
然后对于这个东西,我们可以考虑拓扑图上dp的方式
来解决
//假设我们添加了一条x->y的边,要想不合法,就是求y->x的路径条数
//所以我们要将令起点,也就是y的初值f[y]=ans
void addedge(int x,int y)
{
nxt[++cnt]=point[x];
to[cnt]=y;
in[y]++;
point[x]=cnt;
}
int qsm(int i,int j)
{
int ans=1;
while (j)
{
if (j&1) ans=ans*i%mod;
i=i*i%mod;
j>>=1;
}
return ans;
}
void tpsort()
{
//cout<<ans<<endl;
for (int i=1;i<=n;i++)
{
if (!in[i]) q.push(i);
}
while (!q.empty())
{
int now = q.front();
q.pop();
//cout<<now<<endl;
//int ymh=0;
//if (now==y) ymh=1;
f[now]=f[now]*qsm(d[now],mod-2)%mod;
//cout<<now<<" "<<f[now]<<endl;
for (int i=point[now];i;i=nxt[i])
{
int p =to[i];
in[p]--;
f[p]=(f[p]+f[now])%mod;
if (!in[p]) q.push(p);
}
}
}
下面是整个的代码
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk makr_pair
#define ll long long
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 2e5+1e2;
const int maxm = 2*maxn;
const int mod = 1e9+7;
int point[maxn],nxt[maxm],to[maxm];
int n,m;
int cnt,in[maxn];
queue<int> q;
int ans;
int f[maxn];
int x,y;
int d[maxn];
//假设我们添加了一条x->y的边,要想不合法,就是求y->x的路径条数
//所以我们要将令起点,也就是y的初值f[y]=ans
void addedge(int x,int y)
{
nxt[++cnt]=point[x];
to[cnt]=y;
in[y]++;
point[x]=cnt;
}
int qsm(int i,int j)
{
int ans=1;
while (j)
{
if (j&1) ans=ans*i%mod;
i=i*i%mod;
j>>=1;
}
return ans;
}
void tpsort()
{
//cout<<ans<<endl;
for (int i=1;i<=n;i++)
{
if (!in[i]) q.push(i);
}
while (!q.empty())
{
int now = q.front();
q.pop();
//cout<<now<<endl;
//int ymh=0;
//if (now==y) ymh=1;
f[now]=f[now]*qsm(d[now],mod-2)%mod;
//cout<<now<<" "<<f[now]<<endl;
for (int i=point[now];i;i=nxt[i])
{
int p =to[i];
in[p]--;
f[p]=(f[p]+f[now])%mod;
if (!in[p]) q.push(p);
}
}
}
signed main()
{
n=read(),m=read(),x=read(),y=read();
for (int i=1;i<=m;i++)
{
int u=read(),v=read();
addedge(u,v);
}
ans=1;
for (int i=2;i<=n;i++)
{
if (i==y) ans=ans*(in[i]+1)%mod,d[i]=in[i]+1;
else ans=ans*in[i]%mod,d[i]=in[i];
}
f[y]=ans;
if (x==1)
{
cout<<ans<<"\n";
return 0;
}
tpsort();
cout<<(ans-f[x]+mod)%mod<<endl;
return 0;
}
洛谷3244 落忆枫音 (拓扑图dp+式子)的更多相关文章
- 洛谷P3244 落忆枫音 [HNOI2015] 拓扑排序+dp
正解:拓扑排序+dp 解题报告: 传送门 我好暴躁昂,,,怎么感觉HNOI每年总有那么几道题题面巨长啊,,,语文不好真是太心痛辣QAQ 所以还是要简述一下题意,,,就是说,本来是有一个DAG,然后后来 ...
- P3244-[HNOI2015]落忆枫音【dp】
正题 题目链接:https://www.luogu.com.cn/problem/P3244 题目大意 给出一个\(\text{DAG}\),保证\(1\)可以到达所有点.然后再加入一条边(之后不一定 ...
- 【BZOJ4011】【HNOI2015】落忆枫音(动态规划)
[BZOJ4011][HNOI2015]落忆枫音(动态规划) 题面 BZOJ 洛谷 Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜 ...
- 【BZOJ】【4011】【HNOI2015】落忆枫音
拓扑排序+DP 题解:http://blog.csdn.net/PoPoQQQ/article/details/45194103 http://www.cnblogs.com/mmlz/p/44487 ...
- BZOJ 4011: [HNOI2015]落忆枫音( dp )
DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...
- 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 \] 意思是我们给每个点选一个父亲 然后我们加了一条边,最后如果还这么统计,那么 ...
- 4011: [HNOI2015]落忆枫音
4011: [HNOI2015]落忆枫音 链接 分析: 原来是一个DAG,考虑如何构造树形图,显然可以给每个点找一个父节点,所以树形图的个数就是$\prod\limits_u deg[u]$. 那么加 ...
- BZOJ 4011 【HNOI2015】 落忆枫音
题目链接:落忆枫音 以下内容参考PoPoQQQ大爷的博客 首先我们先来考虑一下如果没有新加入的那条边,答案怎么算. 由于这是一个\(DAG\),所以我们给每个点随便选择一条入边,最后一定会构成一个树形 ...
随机推荐
- Go测试--性能测试分析
目录 前言 认识数据 benchstat 分析一组样本 分析两组样本 小结 前言 benchmark测试是实际项目中经常使用的性能测试方法,我们可以针对某个函数或者某个功能点增加benchmark测试 ...
- 学习小计: Kaggle Learn Embeddings
Embedding表示map f: X(高维) -> Y(低维),减小数据维度,方便计算+提高准确率. 参看Kaggle Learn:https://www.kaggle.com/learn/e ...
- vue 嵌入倒计时组件( 亲测可用 )
由于花费了我不少时间才找到的组件,所以记录一下,后面方便自己好找一些,也算是分享出来给各位前端一起用. npm 下载npm install vue2-flip-countdown --save tem ...
- redis未授权getshell的4种方式
前言 redis未授权漏洞或弱口令一直是很有用的渗透突破口,最近正好闲的无事就拿redis来测试一些,做一个简单的收集,方便自己日后的回顾. 漏洞描述 Redis 默认情况下,会绑定在 0.0.0.0 ...
- 【linux】 linux超实用命令整理
linux实用命令整理 由于开发过程中经常接触linux系统进行各种情况下的操作,故开此博客整理生产环境下操作命令集,温故而知新. 系统命令 快捷键操作命令 1.tab //命令或路径等的补全键,li ...
- 《Go语言圣经》阅读笔记:第三章基础数据类型
第三章 基础数据类型 Go语言将数据类型分为四类: 基础类型 数字 整数 浮点数 复数 字符串 布尔 复合类型 数据 结构体 引用类型 指针 切片 字典 函数 通道 接口类型 在此章节中先介绍基础类型 ...
- 交换机之vlan详解
一.为什么需要VLAN 1.1.什么是VLAN? VLAN(Virtual LAN),翻译成中文是"虚拟局域网".LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算 ...
- iNeuOS工业互联平台,PLC监测与控制应用过程案例。新闻:.NET 6 RC1 正式发布
目 录 1. 概述... 1 2. 平台演示... 2 3. 应用过程... 2 1. 概述 iNeuOS工业互联网操作系统主要使用.netcore 3. ...
- pymysql基础教程
pymysql基础教程 1.下载pymysql 在命令框输入指令即可 pip install pymysql 2.连接pymysql 连接数据库: import pymysql conn = pymy ...
- Java技术开发专题系列之【Guava RateLimiter】针对于限流器的入门到精通(针对于源码分析介绍)
Guava包中限流实现分析 RateLimiter 之前的文章中已经介绍了常用的限流算法,而google在Java领域中使用Guava包中的限流工具进行服务限流. 回顾使用案例 Google开源工具包 ...