正题
证明啥的都不用管,这篇Blog里面的记住就行了.
首先LGV引理只在DAG上有效.
对于一条路径,我们定义它的权值为路径S上边权之积记为
现在有k个起点,k个终点,对于一对起终点,我们定义,S是起终点的任意一条路径.
我们将放进一个k*k的矩阵当中,第i行第j列为.
我们对这个矩阵求行列式,就有:
前面的P枚举的是一个排列,指的是逆序对个数,后面的prod枚举的是每一组从的路径Q,这些路径要满足互不相交,每一组路径的权值就是每条路径权值乘起来.
好像并不能做什么题?
发现当只用数路径条数的时候,也就是边权为1,而且满足存在i!=Pi,全都是相交路径,那么行列式就恰好是ai到bi的不相交路径条数.
目前只会板子emm
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const int mod=998244353;
int ksm(int x,int t){
int tot=1;
while(t){
if(t&1) tot=1ll*tot*x%mod;
x=1ll*x*x%mod;
t/=2;
}
return tot;
}
int n,m,a[N],b[N],fac[2000010],inv[2000010],T;
struct Matrix{
int d[N][N];
int gause(){
int ans=1;
for(int i=1;i<=m;i++){
int wt=ksm(d[i][i],mod-2);
for(int j=i+1;j<=m;j++) if(d[j][i]){
int tmp=1ll*wt*d[j][i]%mod;
for(int k=i;k<=m;k++)
d[j][k]+=mod-1ll*d[i][k]*tmp%mod,d[j][k]>=mod?d[j][k]-=mod:0;
}
ans=1ll*ans*d[i][i]%mod;
}
return ans;
}
}M;
int C(int x,int y){
return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod;
}
int main(){
scanf("%d",&T);
fac[0]=1;for(int i=1;i<=2000000;i++) fac[i]=1ll*fac[i-1]*i%mod;
inv[2000000]=ksm(fac[2000000],mod-2);for(int i=1999999;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
while(T--){
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d %d",&a[i],&b[i]);
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
if(a[i]<=b[j]) M.d[i][j]=C(n-1+b[j]-a[i],b[j]-a[i]);
else M.d[i][j]=0;
printf("%d\n",M.gause());
}
}