社区讨论

请问为什么我求行列式的时候不在交换两行时答案取反也能过?

P5807【模板】BEST 定理 / Which Dreamed It参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo8pvatw
此快照首次捕获于
2023/10/27 22:36
2 年前
此快照最后确认于
2023/10/27 22:36
2 年前
查看原帖
行列式计算好像是要在高斯消元时交换两行时取反的?但是我交了两份取反和不取反都能过。请问是我代码的问题还是数据不够强?
CPP
#include<cstdio>
#include<iostream>
#include<bits/stdc++.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
ll Read()
{
	int t1=1;
	char c=getchar();
	while ((c<'0'||c>'9')&&c!='-') c=getchar();
	if (c=='-') t1=-1,c=getchar();
	ll t=c-'0'; c=getchar();
	while (c>='0'&&c<='9') t=(t<<3)+(t<<1)+c-'0',c=getchar();
	return t*t1;
}
const ll M=1e6+3;
ll inv[M+5],Jie[M+5];
int T,n;
struct Node
{
	int In,Out,bh;
	vector <int> v;
}s[101],t[101];
int rk[101];
ll a[101][101];
int cc=0; 
void Gauss()
{
	cc=0;
	for (int i=2;i<=n;i++)
	{
		for (int j=i;j<=n;j++)
		{
			if (a[j][i])
			{
				for (int k=2;k<=n;k++) swap(a[i][k],a[j][k]);
				if (j!=i) cc++;
				break;
			}
		}
		if (!a[i][i]) continue;
		for (int j=i+1;j<=n;j++)
		{
			if (a[j][i])
			{
				ll t=a[j][i]*inv[a[i][i]]%M;
				for (int k=i;k<=n;k++) a[j][k]=(a[j][k]-a[i][k]*t%M+M)%M;
			}
		}
	}
}
int main()
{
//	freopen("data.in","r",stdin);
	inv[1]=1;
	for (int i=2;i<M;i++) inv[i]=inv[M%i]*(M-M/i)%M;
	Jie[0]=1;
	for (int i=1;i<M;i++) Jie[i]=Jie[i-1]*i%M;
	T=Read(); 
	while (T--)
	{
		n=Read();
		for (int i=1;i<=n;i++)
		{
			s[i].v.clear();
			s[i].In=s[i].Out=0;
			for (int j=1;j<=n;j++) a[i][j]=0;
		}
		for (int i=1;i<=n;i++)
		{
			s[i].bh=i;
			s[i].Out=Read();
			for (int t=0;t<s[i].Out;t++) s[i].v.push_back(Read()),s[s[i].v[t]].In++;
		}
		int tem=n; n=0;
		for (int i=1;i<=tem;i++)
		{
			if (s[i].Out!=0||s[i].In!=0||s[i].bh==1) t[++n]=s[i],rk[s[i].bh]=n;
		}
		bool pd=1;
		for (int i=1;i<=n;i++)
		{
			if (t[i].In!=t[i].Out)
			{
				pd=0;
				printf("0\n");
				break;
			}
		}
		if (!pd) continue;
		for (int i=1;i<=n;i++)
		{
			for (int j=0;j<t[i].Out;j++)
			{
				a[i][rk[t[i].v[j]]]--,a[i][i]++;
				if (a[i][rk[t[i].v[j]]]<0) a[i][rk[t[i].v[j]]]+=M;
				if (a[i][i]>=M) a[i][i]-=M;
			}
		}cc=0;
		Gauss();
		ll ans=1;
		for (int i=2;i<=n;i++) ans=ans*a[i][i]%M;
//		printf("!%d\n",cc);
		if (cc%2==1) ans=(M-ans)%M;//就是这里!!!!!!
		//printf("num:%lld\n",ans);
		for (int i=1;i<=n;i++)
		{
			if (t[i].bh==1) ans=ans*Jie[t[i].Out]%M;
			else ans=ans*Jie[t[i].Out-1]%M;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...