题目描述:

给出一个 \(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的更多相关文章

  1. [AirFlow]AirFlow使用指南三 第一个DAG示例

    经过前两篇文章的简单介绍之后,我们安装了自己的AirFlow以及简单了解了DAG的定义文件.现在我们要实现自己的一个DAG. 1. 启动Web服务器 使用如下命令启用: airflow webserv ...

  2. 调度系统Airflow的第一个DAG

    Airflow的第一个DAG 考虑了很久,要不要记录airflow相关的东西, 应该怎么记录. 官方文档已经有比较详细的介绍了,还有各种博客,我需要有一份自己的笔记吗? 答案就从本文开始了. 本文将从 ...

  3. 抓到Dubbo异步调用的小BUG,再送你一个贡献开源代码的机会

    hello,大家好呀,我是小楼. 最近一个技术群有同学at我,问我是否熟悉Dubbo,这我熟啊~ 他说遇到了一个Dubbo异步调用的问题,怀疑是个BUG,提到BUG我可就不困了,说不定可以水,哦不.. ...

  4. Python You-Get (送你一个免广告的视频和音乐网站 VIP)

    You-get可以在仅仅提供URL情况下就可以实现下载视频.图片.音乐等信息.也可以通过播放器在线观看视频或听音乐,重要的是再也不用烦恼弹出的广告了,如果你想观看视频,但又不想观看广告,并且你还想把视 ...

  5. 谁说 Vim 不好用?送你一个五彩斑斓的编辑器!

    相信大家在使用各种各样强大的 IDE 写代码时都会注意到,代码中各种类型的关键字会用独特的颜色标记出来,然后形成一套语法高亮规则.这样不仅美观,而且方便代码的阅读. 而在上古神器 Vim 中,我们通常 ...

  6. 送你一个Python 数据排序的好方法

    摘要:学习 Pandas排序方法是开始或练习使用 Python进行基本数据分析的好方法.最常见的数据分析是使用电子表格.SQL或pandas 完成的.使用 Pandas 的一大优点是它可以处理大量数据 ...

  7. uva1201 DAG 最小路径覆盖,转化为 二分图

    大白例题P356 你在一座城市里负责一个大型活动的接待工作.你需要去送m个人从出发地到目的地,已知每个人的出发时间出发地点,和目的地点,你的任务是用尽量少的出租车送他们,使得每次出租车接客人,至少能提 ...

  8. UVALive-3126 Taxi Cab Scheme (DAG的最小路径覆盖)

    题目大意:要给n个人安排车,已知每个人的出发时间和起点与终点,问最少需要安排几辆车才能完成任务. 题目分析:最小路径覆盖.如果送完a到目的地后能在b出发之前赶来接b,那么连一条有向边a->b,最 ...

  9. 【LA3126 训练指南】出租车 【DAG最小路径覆盖】

    题意 你在一座城市里负责一个大型活动的接待工作.明天将有m位客人从城市的不同的位置出发,到达他们各自的目的地.已知每个人的出发时间,出发地点和目的地.你的任务是用尽量少的出租车送他们,使得每次出租车接 ...

随机推荐

  1. 使用requireJS

    什么是require? require是AMD模块化规范的具体实现. 目前,通行的js模块化规范有两种,CommonJS和AMD. CommonJS和AMD有什么不同呢? CommonJS主要用于服务 ...

  2. 关于Mac设置alias别名访问服务器

    1.首先要安装zsh[链接]robbyrussell/oh-my-zsh 什么是 oh-my-zsh (官网) 两种下载方式 如下图所示,下载安装成功 vi ~/.zshrc发开 打开zsh配置文件 ...

  3. jq实现碰到边缘反弹的动画

    先上效果图: 录出来有点卡顿的赶脚,实际上还是挺顺畅的. 1.HTML: <div class="box"></div> 2.CSS: body{ back ...

  4. ionic2+Angular 组件(多个组件)浅谈

    第一步,新建组件: ionic g component product-img-list 命令执行成功之后项目中生成的文件: 第二步:生成文件解析: ①product-img-list.ts impo ...

  5. B站标题/子标题/url爬取示例(requests+re)

    #coding:utf-8 __author__ = "zhoumi" 3 import requests import re import urllib ''' 本文档目的在于获 ...

  6. object类的equals方法简介 & String类重写equals方法

    object类中equals方法源码如下所示 public boolean equals(Object obj) { return this == obj; } Object中的equals方法是直接 ...

  7. Java经典编程题50道之四十七

    读取7个数(1~50)的整数值,每读取一个值,程序打印出该值个数的*. public class Example47 {    public static void main(String[] arg ...

  8. centos7 yum与Python3冲突

    虽然标题不严谨,但是,我自己尝试了多次,在安装了Python3.6后,yum无法同步Python.所以采用网上抄来抄去的做法,将yum指定使用Python2,凡是需要安装与Python相关的模块,使用 ...

  9. MysqL 主从事务数据安全之sync_binlog

    sync_binlog:是MySQL 的二进制日志(binary log)同步到磁盘的频率(刷新二进制日志到磁盘),默认是0,意味着mysql并不刷新,由操作系统自己决定什么时候刷新缓存到持久化设置, ...

  10. 出行服务类API调用的代码示例合集:长途汽车查询、车型大全、火车票查询等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 长途汽车查询:全国主要城市的长途汽车时刻查询,汽车站查询 车型大全 ...