HDU 6116 路径计数
HDU 6116 路径计数
普通生成函数常用于处理组合问题,指数生成函数常用于处理排列问题。
考虑 对于 $ a $ 个 $ A $ 分为很多堆,这么分的方案数是 $ C_{a-1}^{i-1} $
然后对于每一堆我们看成一个数来放,并且所有堆都这样做,这样的话总的方案数量是 $ \frac{(i+j+k+l)!}{i!j!k!l!} $
就算所有一堆看成的数的排列是不存在相邻相等的,至少都有 $ n-i-j-k-l $ 对相邻的相同的数。
然后就可以容斥了,枚举 $ i+j+k+l $ 直接计算就好了。
$ ans = \displaystyle \sum_{x=1}^{n} (-1)^{n-x} x! \sum_{i+j+k+l=x} \frac{C_{a-1}^{i-1} C_{b-1}^{j-1} C_{c-1}^{k-1} C_{d-1}^{l-1}}{i ! j ! k ! l !} $
后面其实就是四个指数生成函数乘积了。
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define P 998244353
#define clr( a ) memset( a , 0 , sizeof a )
typedef long long ll;
int wn[2][MAXN];
int Pow( int x , int y ) {
int res=1;
while(y) {
if(y&1) res=res*(ll)x%P;
x=x*(ll)x%P,y>>=1;
}
return res;
}
void getwn(int l) {
for(int i=1;i<(1<<l);i<<=1) {
int w0=Pow(3,(P-1)/(i<<1)),w1=Pow(3,P-1-(P-1)/(i<<1));
wn[0][i]=wn[1][i]=1;
for(int j=1;j<i;++j)
wn[0][i+j]=wn[0][i+j-1]*(ll)w0%P,
wn[1][i+j]=wn[1][i+j-1]*(ll)w1%P;
}
}
int rev[MAXN];
void getr(int l) { for(int i=1;i<(1<<l);++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1); }
void NTT(int *A,int len,int f) {
for(int i=0;i<len;++i) if(rev[i]<i) swap(A[i],A[rev[i]]);
for(int l=1;l<len;l<<=1)
for(int i=0;i<len;i+=(l<<1))
for(int k=0;k<l;++k) {
int t1=A[i+k],t2=A[i+l+k]*(ll)wn[f][l+k]%P;
A[i+k]=(t1+t2)%P;
A[i+l+k]=(t1-t2+P)%P;
}
if( f == 1 ) for(int inv=Pow(len,P-2),i=0;i<len;++i) A[i]=A[i]*(ll)inv%P;
}
int a , b , c , d;
int J[MAXN] , invJ[MAXN] , inv[MAXN];
int cc( int a , int b ) {
if( b > a ) return 0;
return 1ll * J[a] * invJ[b] % P * invJ[a - b] % P;
}
int A[MAXN] , B[MAXN] , C[MAXN] , D[MAXN];
int main() {
J[0] = inv[1] = invJ[0] = J[1] = invJ[1] = 1;
for( int i = 2 ; i < MAXN ; ++ i ) inv[i] = 1ll * ( P - P / i ) * inv[P % i] % P , J[i] = 1ll * J[i - 1] * i % P , invJ[i] = 1ll * invJ[i - 1] * inv[i] % P;
while( cin >> a >> b >> c >> d ) {
clr( A ) , clr( B ) , clr( C ) , clr( D );
int n = a + b + c + d;
for( int i = 1 ; i <= a ; ++ i ) A[i] = 1ll * cc( a - 1 , i - 1 ) * invJ[i] % P;
for( int i = 1 ; i <= b ; ++ i ) B[i] = 1ll * cc( b - 1 , i - 1 ) * invJ[i] % P;
for( int i = 1 ; i <= c ; ++ i ) C[i] = 1ll * cc( c - 1 , i - 1 ) * invJ[i] % P;
for( int i = 1 ; i <= d ; ++ i ) D[i] = 1ll * cc( d - 1 , i - 1 ) * invJ[i] % P;
int len = 1 , l = 0;
while( len <= n ) len <<= 1 , ++ l;
getwn( l ) , getr( l );
NTT( A , len , 0 ) , NTT( B , len , 0 ) , NTT( C , len , 0 ) , NTT( D , len , 0 );
for( int i = 0 ; i < len ; ++ i ) A[i] = 1ll * A[i] * B[i] % P * C[i] % P * D[i] % P;
NTT( A , len , 1 );
ll res = 0;
for( int i = 1 ; i <= n ; ++ i )
res += ( ( n - i & 1 ) ? -1ll : 1ll ) * J[i] * A[i] % P , res += P , res %= P;
cout << res << endl;
}
}
HDU 6116 路径计数的更多相关文章
- hdu 5868 Polya计数
Different Circle Permutation Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K ...
- 51 nod 1610 路径计数(Moblus+dp)
1610 路径计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 路径上所有边权的最大公约数定义为一条路径的值. 给定一个有向无环图.T次修改操作,每次修改一 ...
- hdu 2865 Polya计数+(矩阵 or 找规律 求C)
Birthday Toy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 蓝桥杯 历届试题 网络寻路(dfs搜索合法路径计数)
X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径 ...
- 堆优化Dijkstra计算最短路+路径计数
今天考试的时候遇到了一道题需要路径计数,然而蒟蒻从来没有做过,所以在考场上真的一脸懵逼.然后出题人NaVi_Awson说明天考试还会卡SPFA,吓得我赶紧又来学一波堆优化的Dijkstra(之前只会S ...
- 【洛谷】P1176: 路径计数2【递推】
P1176 路径计数2 题目描述 一个N×N的网格,你一开始在(1,1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N,N),即右下角有多少种方法. 但是这个问题太简单了,所以 ...
- hdu 6010 路径交
hdu 6010 路径交(lca + 线段树) 题意: 给出一棵大小为\(n\)的树和\(m\)条路径,求第\(L\)条路径到第\(R\)条路径的交的路径的长度 思路: 本题的关键就是求路径交 假设存 ...
- 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学
牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...
- 洛谷——P1176 路径计数2
P1176 路径计数2 题目描述 一个N \times NN×N的网格,你一开始在(1,1)(1,1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N,N)(N,N),即右下角有 ...
随机推荐
- 半天撸一个简易版mybatis
为什么需要持久层框架? 首先我们先看看使用原生jdbc存在的问题? public static void main(String[] args) { Connection connection = n ...
- Gopher们写if err != nil是否腻了?
效果 go里面没有try catch,比较类似的有panic() 和 recover()机制,但是代价太大了,他们的场景更多使用在"程序异常,无法继续往下执行了这种场景",比如配置 ...
- 一套比较好用的公众号UI框架-weui
最近工作原因 需要在pd端弄一套js类似bootstrap框架 由于使用环境是在公众号终端用的比较多! 类似上面这样的样式 所以我从微信官方开始找起 最后找到了WEUI 还别说 真的挺好用的 这是大佬 ...
- 有了 HTTP 协议,为什么还需要 Websocket?
WebSocket 是一种基于 TCP 连接上进行全双工通信的协议,相对于 HTTP 这种非持久的协议来说,WebSocket 是一个持久化网络通信的协议. 它不仅可以实现客户端请求服务器,同时可以允 ...
- objdump--反汇编查看
转载:objdump命令_Linux objdump 命令用法详解:显示二进制文件信息 (linuxde.net) objdump命令 编程开发 objdump命令是用查看目标文件或者可执行的目标文件 ...
- 清除行列 牛客网 程序员面试金典 C++ Python
清除行列 牛客网 程序员面试金典 C++ Python 题目描述 请编写一个算法,若N阶方阵中某个元素为0,则将其所在的行与列清零. 给定一个N阶方阵int[]mat和矩阵的阶数n,请返回完成操作后的 ...
- 最接近的数 牛客网 程序员面试金典 C++ Python
最接近的数 牛客网 程序员面试金典 C++ Python 题目描述 有一个正整数,请找出其二进制表示中1的个数相同.且大小最接近的那两个数.(一个略大,一个略小) 给定正整数int x,请返回一个ve ...
- 解决CentOS添加新网卡后找不到网卡配置文件,配置多网卡并设置静态路由
参考文章 https://blog.csdn.net/qq_36512792/article/details/79787649 使用VMware Workstation虚拟机安装好CentOS7虚拟机 ...
- 自动下载MarkDown格式会议论文的程序
近期师兄发给我一个压缩包让我整理文献,而我发现压缩包里的内容是这样: 这样: 和这样的: 我大概看了一下,可能有270多篇文章是这种格式,俗话说的好,没有困难的工作,只有勇敢的研究僧.所以决定用Pyt ...
- .NET Protobuf包装器库
Wodsoft Protobuf Wrapper 内容 关于 需求 安装 用法 序列化 反序列化 字段定义 字段排序 非空构造函数对象 获取Protobuf包装器 高级 支持的属性类型与Protobu ...