「SWTR-05」Chain
时间:2021-10-11
本文章向大家介绍「SWTR-05」Chain,主要包括「SWTR-05」Chain使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Description
给定一个 DAG,每次询问如果删除 \(k\leq 15\) 个点,还剩下多少条入度为零的点到出度为零的点的路径。新增的路径不参与统计。
Solution
唯一可做题,其他的都没什么思路/kel。
\(k\) 很小,容易想到一个枚举子集的做法,那么只需要预处理出每两个点之间的距离。可以按拓扑序删点,然后再一遍拓扑求出所有点到当前点的距离。配合容斥可以过前 75%,复杂度 \(O(nm+q2^k)\)。
发现只需要知道最后一个点是哪个点,把这 \(k\) 个点按拓扑序排序,然后考虑 dp。\(dp_{i,j}\) 表示选了 \(j\) 个点,最后一个点是第 \(i\) 个的从入度为零的点到 \(i\) 的路径条数。那么统计答案就只需要乘上 \((-1)^j\) 的容斥系数,再乘上点到终点的方案数。这样单次询问就是 \(O(k^3)\)。
再次观察,发现并不需要知道选了多少个,只需要在转移的时候容斥,那么就可以删掉一维。单次 \(O(k^2)\)。
#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,flag=1; char c=getchar();
while(c<'0'||c>'9'){if(c=='-')flag=0;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
return flag? x:-x;
}
const int N=2e3+7;
const int Mod=1e9+7;
queue<int> Q;
vector<int> G[N];
int dfn[N],in[N],dis[N][N],In[N],a[N],dp[16];
inline bool Cmp(int x,int y){return dfn[x]<dfn[y];}
int main(){
freopen("foodchain.in","r",stdin);
freopen("foodchain.out","w",stdout);
int n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
G[u].push_back(v),In[v]++;
}
for(int u=1;u<=n;u++){
if(!G[u].size()) G[u].push_back(n+1),In[n+1]++;
if(!In[u]) G[0].push_back(u),In[u]++;
in[u]=In[u];
}
Q.push(0); int timer=0;
while(!Q.empty()){
int u=Q.front(); Q.pop(); dfn[u]=++timer;
for(int v:G[u]) if(!(--in[v])) Q.push(v);
}
for(int i=0;i<=n+1;i++) a[i]=i;
sort(a,a+1+n+1,Cmp);
for(int i=0;i<=n+1;i++){
const int U=a[i];
for(int v=0;v<=n+1;v++) in[v]=In[v];
dis[U][U]=1;
for(int j=i;j<=n+1;j++)
if(!in[a[j]]) Q.push(a[j]);
while(!Q.empty()){
int u=Q.front(); Q.pop();
for(int v:G[u]){
dis[U][v]=(dis[U][v]+dis[U][u])%Mod;
if(!(--in[v])) Q.push(v);
}
}
for(int v:G[U]) --In[v];
}
int q=read();
while(q--){
int k=read();
for(int i=1;i<=k;i++) a[i]=read();
sort(a+1,a+1+k,Cmp);
for(int i=1;i<=k;i++)
dp[i]=Mod-dis[0][a[i]];
for(int i=1;i<=k;i++)
for(int j=1;j<i;j++)
dp[i]=(dp[i]-1ll*dp[j]*dis[a[j]][a[i]]%Mod+Mod)%Mod;
int ans=dis[0][n+1];
for(int i=1;i<=k;i++)
ans=(ans+1ll*dp[i]*dis[a[i]][n+1]%Mod)%Mod;
printf("%d\n",ans);
}
}
原文地址:https://www.cnblogs.com/wwlwQWQ/p/15394254.html
- 计算资源及编程-仅针对生信人员
- 从WGS测序得到的VCF文件里面提取位于外显子区域的【直播】我的基因组84
- 基因组重测序的unmapped reads assembly探究 【直播】我的基因组86
- Centos 下非 Root 安装 Microsoft R Open
- 下载TCGA所有癌症的maf文件做signature分析
- 比对NR库看看物种分布【直播】我的基因组88
- 探究某个基因的外显子覆盖度情况【直播】我的基因组87
- PHP底层的运行机制与原理
- CHROME开发者工具的小技巧
- 48条高效率的PHP优化写法
- 生信蓝领,一个不舍得分享的高通量数据分析框架
- 为什么in_array(0, ['a', 'b', 'c'])返回true
- Java 10 新特性解密,引入类型推断机制,将于 2018 年 3 月 20 日发布
- 肿瘤全外显子测序数据分析流程大放送
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python自学成才之路 文件读写操作
- go 中string[0]到底是rune还是byte?
- python自学成才之路 类详细用法
- Linux 监控之 IO
- python自学成才之路 函数详细用法
- 你所不知道的TIME_WAIT和CLOSE_WAIT
- linux之网络
- linux vim编辑器之常用指令
- saltstack手册(含官方pdf)
- 详解Go变量类型的内存布局
- linux vim 编辑器之多文件多窗口编辑
- 深入解析 Go 中 Slice 底层实现
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)
- linux文件时间属性 查看和修改文件时间
- Linux硬连接和软连接详解