考虑使用拉格朗日乘数法
$$
求偏导
可得
代入运算可得
代码
#include <bits/stdc++.h> using namespace std; #define paii pair<int,int> #define fr first #define sc second typedef long long ll; const ll mod=998244353; ll a[410][410]; ll b[410]; ll c[410]; int n,is[410],js[410]; void exgcd(int a,int b,int &x,int &y){ if(!b)return x=1,y=0,void(); exgcd(b,a%b,y,x);y-=x*(a/b); } int inv(int p){ int x,y;exgcd(p,mod,x,y); return (x+mod)%mod; } void inv(){ for(int k=1;k<=n;k++){ for(int i=k;i<=n;i++) // 1 for(int j=k;j<=n;j++)if(a[i][j]){ is[k]=i,js[k]=j;break; } for(int i=1;i<=n;i++) // 2 swap(a[k][i],a[is[k]][i]); for(int i=1;i<=n;i++) swap(a[i][k],a[i][js[k]]); if(!a[k][k]){ puts("No Solution"); exit(0); } a[k][k]=inv(a[k][k]); // 3 for(int j=1;j<=n;j++)if(j!=k) // 4 (a[k][j]*=a[k][k])%=mod; for(int i=1;i<=n;i++)if(i!=k) // 5 for(int j=1;j<=n;j++)if(j!=k) (a[i][j]+=mod-a[i][k]*a[k][j]%mod)%=mod; for(int i=1;i<=n;i++)if(i!=k) // 就是这里不同 a[i][k]=(mod-a[i][k]*a[k][k]%mod)%mod; } for(int k=n;k;k--){ // 6 for(int i=1;i<=n;i++) swap(a[js[k]][i],a[k][i]); for(int i=1;i<=n;i++) swap(a[i][is[k]],a[i][k]); } } void work() { while(~scanf("%d",&n)){ memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); memset(is,0,sizeof(is)); memset(js,0,sizeof(js)); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%lld",&a[i][j]); a[i][j]=(a[i][j]%mod+mod)%mod; } } for(int i=1;i<=n;i++){ scanf("%lld",&b[i]); b[i]=(b[i]%mod+mod)%mod; } inv(); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ c[i]=(c[i]+a[j][i]*b[j]%mod)%mod; } } for(int i=1;i<=n;i++){ c[i]=(c[i]*b[i])%mod; } ll ans=0; for(int i=1;i<=n;i++){ ans=(ans+c[i])%mod; } printf("%lld\n",(ans+mod)%mod); } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int T=1; //scanf("%d",&T); //cin>>T; while(T--){ work(); } }