double的精度误差究竟有多大?
  • 板块学术版
  • 楼主Rain_chr
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/11/27 19:38
  • 上次更新2024/11/27 21:08:53
查看原帖
double的精度误差究竟有多大?
684254
Rain_chr楼主2024/11/27 19:38

本人在写 CF53E 的时候,一眼秒掉了一个二项式反演+矩阵树定理的做法,结果求行列式用的是 double WA on test 11,改成剩余系下高消才过。

本题保证 n10,ai10n\le 10,a_i\le 10,行列式的值不大于 nn2=108n^{n-2}=10^8,在这么小的范围下为什么 double 求行列式的值能够与正确值差几百?

代码:

  1. double

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=20;
int work(double a[N][N],int n)
{   
    for(int i=1;i<=n;i++)
    {
        int d=0;
        for(int j=1;j<=n;j++)
            d+=a[i][j],a[i][j]=-a[i][j];
        a[i][i]+=d;
    }
    n--;
    double ans=1;
    for(int i=1;i<=n;i++)
    {
        int Max=i;
        for(int j=i+1;j<=n;j++)
            if(abs(a[j][i])>abs(a[Max][i]))
                Max=i;
        if(abs(a[Max][i])<1e-8) return 0;
        if(Max!=i) swap(a[Max],a[i]),ans=-ans;
        ans*=a[i][i];
        for(int j=i+1;j<=n;j++)
        {
            double t=a[j][i]/a[i][i];
            for(int k=i;k<=n;k++) a[j][k]-=a[i][k]*t;
        }
    }
    return ans;
}
  1. int
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=20;
bool a[N][N];
const int mod=998244353;
int ksm(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod,b>>=1;
    }
    return ans;
}
int work(int a[N][N],int n)
{   
    for(int i=1;i<=n;i++)
    {
        int d=0;
        for(int j=1;j<=n;j++)
            d+=a[i][j],a[i][j]=(mod-a[i][j])%mod;
        a[i][i]+=d;
    }
    n--;
    int ans=1;
    for(int i=1;i<=n;i++)
    {
        int Max=i;
        for(int j=i+1;j<=n;j++)
            if(a[j][i]>a[Max][i])
                Max=j;
        if(!a[Max][i]) return 0;
        if(Max!=i) swap(a[Max],a[i]),ans=mod-ans;
        ans=ans*a[i][i]%mod;
        for(int j=i+1;j<=n;j++)
        {
            int t=a[j][i]*ksm(a[i][i],mod-2)%mod;
            for(int k=i;k<=n;k++) a[j][k]=(a[j][k]+mod-a[i][k]*t%mod)%mod;
        }
    }
    return ans;
}
2024/11/27 19:38
加载中...