[JZOJ5511] 送你一个DAG
题目描述:
给出一个 \(n\) 个点 \(m\) 条边的 \(DAG\) 和参数 \(k\)。
定义一条经过 \(l\) 条边的路径的权值为 \(l^k\).
对于 \(i = 1…n\), 求出所有 \(1\) 到 \(i\) 的路径的权值之和, 对 \(998244353\) 取模.
对于前 \(20\)% 的数据, \(n ≤ 2000\),\(m ≤ 5000\);
对于另 \(10\)% 的数据, \(k = 1\);
对于另 \(20\)% 的数据, \(k ≤ 30\);
对于 \(100\)% 的数据, \(1 ≤ n ≤ 100000\),\(1 ≤ m ≤ 200000\),\(0 ≤ k ≤ 500\),
保证从 \(1\) 出发可以到达每个点, 可能会有重边。
题目解法:
前\(50\)%直接二项式定理,时间复杂度为\(O(nk^2)\)。
对于每一个点 \(i\),题目需要求的是:
\(Ans_i = \sum len(i)^k\)
根据组合数学,有:
\[n^m = \sum_{j=1}^{min(n,m)}S_m^j*\prod_{n-j+1}^n =\sum_{j=1}^nS_m^j*{j!}C_n^j\]
其中\(S_n^m\)为斯特林数,具体含义见这里。
其实就是先选择\(j\)个盒子,然后把\(m\)个小球放到这\(j\)个盒子中。
那么带入本题中:
\(Ans_i = \sum len(i)^k = \sum\sum_{j=1}^{min(k,len(i))}S_k^j*{j!}*C_{len(i)}^j\)
然后是关键的一步:
\[\sum \sum_{j=1}^{k}S_k^j*{j!}*C_{len(i)}^j = \sum_{j=1}^kS^j_k*{j!} \sum C_{len(i)}^j\]
注意到这里把组合数\(C_{len(i)}^j\)提了出来,那么其实就是分离了变量\(len(i)\)
这个式子的前面部分中的\(S_k^j*{j!}\)可以直接算,所以只要处理组合数即可。
令\(F_{u,j} = \sum C_{len(u)}^j\)。
那么考虑由\(u\)转移到\(v\),那么即为:\(C_{len(i)}^j\) 变为 \(C_{len(i)+1}^j\)
由组合数公式可以知道:\(C_n^m = C_{n-1}^{m-1}+C_{n-1}^{m}\)
所以\(F_{i,j}\)的转移为:$ F_{v,j} = F_{u,j-1} + F_{u,j}。$
在\(TopSort\)时跑这个\(DP\),做出\(F_{i,j}\),然后带入上面的公式中即可计算\(Ans_i\)了。
总的时间复杂度为\(O(nk)\),可以跑过所有数据点。
实现代码
#include<bits/stdc++.h>
#define IL inline
#define ll long long
#define RG register
#define mod 998244353
using namespace std;
IL int gi(){
RG int date = 0, m = 1; RG char ch = 0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch = getchar();
if(ch == '-'){m = -1; ch = getchar();}
while(ch>='0'&&ch<='9'){date=date*10+ch-'0';ch=getchar();}
return date*m;
}
int n,m,k,init[100005];
ll f[100005][505] , g[505][505] , fac , ans[100005];
struct Road{int to,next;}t[300005]; int head[100005],cnt;
queue<int>Q;
int main(){
n = gi(); m = gi(); k = gi();
for(int i = 1; i <= m; i++){
int u = gi() , v = gi();
t[++cnt] = (Road){v,head[u]}; head[u] = cnt;
init[v] ++;
}
while(!Q.empty())Q.pop();
for(int i = 1; i <= n; i ++)if(!init[i]){f[i][0] = 1; Q.push(i);}
g[0][0] = 1; //g[i][j] 把i个有异球 放到 j个无异盒 里。
for(int i = 1; i <= k; i ++)
for(int j = 0; j <= i; j ++){
g[i][j] = g[i][j] + 1ll*g[i-1][j]*j%mod;
if(j)g[i][j] = (g[i][j] + g[i-1][j-1])%mod;
}
while(!Q.empty()){
RG int u = Q.front(); Q.pop();
for(int i = head[u]; i; i = t[i].next){
int v = t[i].to;
init[v] --; if(!init[v])Q.push(v);
for(int j = 0; j <= k; j ++){
if(j)f[v][j] = (f[v][j] + f[u][j-1])%mod;
f[v][j] = (f[v][j] + f[u][j]) %mod;
}
}
}
for(int i = 1; i <= n; i ++){
fac = 1; ans[i] = 0;
for(ll j = 1; j <= k; j ++){
fac = 1ll*fac*j%mod; if(fac>=mod)fac%=mod;
ans[i] = (ans[i] + 1ll*fac*g[k][j]%mod*f[i][j]) %mod;
}
}
for(int i = 1; i <= n; i ++)printf("%lld\n",ans[i]);
return 0;
}
[JZOJ5511] 送你一个DAG的更多相关文章
- [AirFlow]AirFlow使用指南三 第一个DAG示例
经过前两篇文章的简单介绍之后,我们安装了自己的AirFlow以及简单了解了DAG的定义文件.现在我们要实现自己的一个DAG. 1. 启动Web服务器 使用如下命令启用: airflow webserv ...
- 调度系统Airflow的第一个DAG
Airflow的第一个DAG 考虑了很久,要不要记录airflow相关的东西, 应该怎么记录. 官方文档已经有比较详细的介绍了,还有各种博客,我需要有一份自己的笔记吗? 答案就从本文开始了. 本文将从 ...
- 抓到Dubbo异步调用的小BUG,再送你一个贡献开源代码的机会
hello,大家好呀,我是小楼. 最近一个技术群有同学at我,问我是否熟悉Dubbo,这我熟啊~ 他说遇到了一个Dubbo异步调用的问题,怀疑是个BUG,提到BUG我可就不困了,说不定可以水,哦不.. ...
- Python You-Get (送你一个免广告的视频和音乐网站 VIP)
You-get可以在仅仅提供URL情况下就可以实现下载视频.图片.音乐等信息.也可以通过播放器在线观看视频或听音乐,重要的是再也不用烦恼弹出的广告了,如果你想观看视频,但又不想观看广告,并且你还想把视 ...
- 谁说 Vim 不好用?送你一个五彩斑斓的编辑器!
相信大家在使用各种各样强大的 IDE 写代码时都会注意到,代码中各种类型的关键字会用独特的颜色标记出来,然后形成一套语法高亮规则.这样不仅美观,而且方便代码的阅读. 而在上古神器 Vim 中,我们通常 ...
- 送你一个Python 数据排序的好方法
摘要:学习 Pandas排序方法是开始或练习使用 Python进行基本数据分析的好方法.最常见的数据分析是使用电子表格.SQL或pandas 完成的.使用 Pandas 的一大优点是它可以处理大量数据 ...
- uva1201 DAG 最小路径覆盖,转化为 二分图
大白例题P356 你在一座城市里负责一个大型活动的接待工作.你需要去送m个人从出发地到目的地,已知每个人的出发时间出发地点,和目的地点,你的任务是用尽量少的出租车送他们,使得每次出租车接客人,至少能提 ...
- UVALive-3126 Taxi Cab Scheme (DAG的最小路径覆盖)
题目大意:要给n个人安排车,已知每个人的出发时间和起点与终点,问最少需要安排几辆车才能完成任务. 题目分析:最小路径覆盖.如果送完a到目的地后能在b出发之前赶来接b,那么连一条有向边a->b,最 ...
- 【LA3126 训练指南】出租车 【DAG最小路径覆盖】
题意 你在一座城市里负责一个大型活动的接待工作.明天将有m位客人从城市的不同的位置出发,到达他们各自的目的地.已知每个人的出发时间,出发地点和目的地.你的任务是用尽量少的出租车送他们,使得每次出租车接 ...
随机推荐
- Jenkins持续集成-自动化部署脚本的实现
要实现Jenkins端的持续集成,其实在CI服务配置端很容易,难点呢?就是如何实现自动化的部署.我的脚本设计就是为了解决以下难题: 难点一.如何使得自动化部署脚本更通用 我用的脚本,依赖依赖一个配置文 ...
- yii2 源码分析Action类分析 (六)
Action类是控制器的基类, <?php namespace yii\base; use Yii; /** * Action是所有控制器动作类的基类,它继承组件类 * * 动作提供了重用动作方 ...
- shell脚本实现nfs服务安装配置,共享文件分发
##############################Deploy nfs######################## echo "start deploy nfs-server& ...
- (转)CocoaPods:管理Objective-c 程序中各种第三方开源库关联
在我们的iOS程序中,经常会用到多个第三方的开源库,通常做法是去下载最新版本的开源库,然后拖拽到工程中. 但是,第三方开源库的数量一旦比较多,版本的管理就非常的麻烦.有没有什么办法可以简化对第三方库的 ...
- 解决react-router4在browserhistory路由下的nginx的白屏或者404问题
使用react-router,官方推荐用browserhistory,美观简洁.但是nginx服务器端的配置也让人头疼. 首先看官方举例的方法: server { location / { try_f ...
- iOS isa指针
在Objective-C中,任何类的定义都是对象.类和类的实例没有任何本质上的区别.任何对象都有isa指针. isa:是一个Class 类型的指针. 每个实例对象有个isa的指针,它指向对象的类,而C ...
- Socket 参数笔记
//服务端@RunWith(JUnit4.class) public class ServerSocketTest { @Test public void testServer() throws IO ...
- 最简化搭建yum仓库
在使用rpm安装软件包时,时常会遇到一些软件依赖性问题,如果是简单的一两个依赖性还是可以手动解决.要是出现大量的依赖性问题的话会让增大工作量.yum是一个很好的前端程序,可解决软件包相关依赖性,可在多 ...
- Jmeter MD5插件
实际业务中,会要求 HTTP 协议中附加 MD5 校验字段, 防止请求参数被恶意篡改, 对于开发同学来说, 这是个很简单的需求. 但是给自动化测试增加了难度, Jmeter 原生不支持这个功能,应测试 ...
- Jenkins构建Android项目持续集成之findbugs的使用
Findbugs简介 关于findbugs的介绍,可以自行百度下,这里贴下百度百科的介绍.findbugs是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题 ...