【行列式】交易(省选模拟Day3)(2022.9.23)
交易 Orzcyr
【问题描述】
给定 n 点 m 边有向无环图,其中没有入度的点被视为源点,没有出度的点被视为
汇点。保证源点和汇点数目相同。
考虑所有把源汇点两两配对,用两两点不相交的路径把它们两两连接的所有方案
如果这个方案中,把源点按标号排序后,得到的对应汇点序列的逆序数对的个数
是奇数,那么 A 给 B 一块钱,否则 B 给 A 一块钱。
问最后 A 的收益,对一个 p 取模。n,m,p 均为整数,p 为质数。
【输入格式】
第一行读入三个数,n,m,p,接下来 m 行,读入有向边。
【输出格式】
一行,输出答案。
【样例输入】
4 4 1000003
2 1
2 4
3 1
3 4
【样例输出】
0
【数据规模与约定】
对于 30%的数据,n<=100
对于 100%的数据,1<=n<=600,1<=m<=50000
解
一看答案逆序对形式即行列式(关于行列式是什么以及行列式的基本变换请自行百度)
把图跑一边求出行列式,类似高消求出行列式的值即答案。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
int f=1,j=0;
char w=getchar();
while(w>'9'||w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
#define int long long
const int N=601,M=100001;
int n,m,mod,s[N],t[N],f[N][N],sum[N][N],ru[N],chu[N],s_len,t_len;
int head[N],to[M],fro[M],tail;
inline void addline(int x,int y){
to[++tail]=y;
fro[tail]=head[x];
head[x]=tail;
ru[y]++,chu[x]++;
return ;
}
void bfs(){
deque<int>p;
for(int i=1;i<=s_len;i++)p.push_back(s[i]),sum[s[i]][s[i]]=1;
while(!p.empty()){
int u=p.front();p.pop_front();
for(int k=head[u];k;k=fro[k]){
int x=to[k];
ru[x]--;
if(!ru[x])p.push_back(x);
for(int i=1;i<=s_len;i++)sum[s[i]][x]+=sum[s[i]][u],sum[s[i]][x]%=mod;
}
}
return ;
}
inline int fastpow(int x,int y){
int ansn=1;
while(y){
if(y&1)ansn=1ll*ansn*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return ansn;
}
int gaos(){
int len=s_len,num=1,ans=1;
for(int i=1;i<=len;i++){
if(!f[i][i]){
int cnt=0;
for(int j=i+1;j<=n;j++){
if(f[j][i]){
swap(f[i],f[j]),num*=-1,cnt++;
break;
}
}
if(!cnt)return 0;
}
for(int j=i+1;j<=len;j++){
if(!f[j][i])continue;
long long k=mod-1ll*fastpow(f[i][i],mod-2)*f[j][i]%mod;
for(int l=i;l<=len;l++)f[j][l]=(f[j][l]+1ll*f[i][l]*k%mod)%mod;
}
}
for(int i=1;i<=len;i++)ans=1ll*ans*f[i][i]%mod;
ans=(ans*num+mod)%mod;
return ans;
}
signed main(){
n=rd(),m=rd(),mod=rd();
for(int i=1;i<=m;i++){
int x=rd(),y=rd();
addline(x,y);
}
for(int i=1;i<=n;i++){
if(!chu[i])t[++t_len]=i;
if(!ru[i])s[++s_len]=i;
}
bfs();
for(int x=1;x<=s_len;x++){
for(int y=1;y<=t_len;y++){
f[x][y]=sum[s[x]][t[y]]%mod;
}
}
printf("%d",gaos());
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了