HDU.3571.N-dimensional Sphere(高斯消元 模线性方程组)

题目链接
高斯消元详解

/*
$Description$
在n维空间中给定n+1个点,求一个点使得这个点到所有点的距离都为R(R不给出)。点的任一坐标|xi|<=1e17.
$Solution$
根据题意可以列出n+1个二元n次方程,相邻的方程相减可以把二次项和R全部约掉,得到n个一元n次方程。
但需要注意这题数据量较大,最大的可能解范围为1e17,如果利用大数(高精...) 乘法的复杂度会很高
可以采用同余的方法,所有运算需要模一个足够大的素数(>1e17),可以用Miller_Rabin生成一个。。还有快速乘就不说了。
这样利用同余方程可以求出一个最小的非负解。
由于这题数据会有负数,而同余求出的是非负数,为消除这种情况,需对所有数值加上一个偏移量1e17,最后的解再减去偏移量。
 */
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=55;
const LL mod=200000000000000003ll;
const LL offset=1e17;

LL A[N][N],B[N];

inline LL read()
{
    LL now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}
inline LL Mult(LL a,LL b)
{
    LL tmp=a*b-(LL)((long double)a/mod*b+1e-8)*mod;
    return tmp<0?tmp+mod:tmp;
}
//#define Add(x,y) ((x)+=(y),(x)>=mod?(x)-=mod:0)
//inline LL Mult(LL a,LL b)
//{
//  LL t=0;
//  for(;b;b>>=1,Add(a,a))
//      if(b&1) Add(t,a);
//  return t;
//}
namespace Gauss
{
    int n;
    LL f[N][N],ans[N];
    LL Exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b) x=1,y=0;
        else Exgcd(b,a%b,y,x),y-=a/b*x;
    }
    LL Inv(LL a)
    {
        LL x,y; Exgcd(a,mod,x,y);
        return (x%mod+mod)%mod;
    }
    void Init()
    {
        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<n; ++j)
                f[i][j]=((A[i+1][j]-A[i][j]<<1)%mod+mod)%mod;
            f[i][n]=((B[i+1]-B[i])%mod+mod)%mod;
        }
    }
    void Solve()
    {
        for(int j=0; j<n; ++j)
        {
            int mxrow=j;
            for(int i=j+1; i<n; ++i)
                if(f[i][j]>f[mxrow][j]) mxrow=i;
            if(mxrow!=j) std::swap(f[mxrow],f[j]);
            LL inv=Inv(f[j][j]);
            for(int i=j+1; i<n; ++i)
                if(f[i][j])
                {
                    LL t=Mult(f[i][j],inv);
                    f[i][j]=0;
                    for(int k=j+1; k<=n; ++k)
                        f[i][k]=((f[i][k]-Mult(t,f[j][k]))%mod+mod)%mod;
                }
        }
        for(int i=n-1; ~i; --i)
        {
            for(int j=i+1; j<n; ++j)
                f[i][n]=(f[i][n]-Mult(ans[j],f[i][j]))%mod;
            (f[i][n]+=mod)%=mod;
            ans[i]=Mult(f[i][n],Inv(f[i][i]));
        }
        for(int i=0; i<n-1; ++i) printf("%lld ",ans[i]-offset);
        printf("%lld\n",ans[n-1]-offset);
//      for(int i=0; i<n-1; ++i) printf("%I64d ",ans[i]-offset);
//      printf("%I64d\n",ans[n-1]-offset);

    }
}

int main()
{
    int t=read(),n;
    for(int kase=1; kase<=t; ++kase)
    {
        memset(B,0,sizeof B);
        Gauss::n=n=read();
        for(int i=0; i<=n; ++i)
            for(int j=0; j<n; ++j)
                A[i][j]=read()+offset,
                B[i]+=Mult(A[i][j],A[i][j]), B[i]>=mod?B[i]-=mod:0;
        printf("Case %d:\n",kase);
        Gauss::Init(), Gauss::Solve();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/8454466.html

时间: 2024-10-25 16:34:29

HDU.3571.N-dimensional Sphere(高斯消元 模线性方程组)的相关文章

hdu 5755(高斯消元——模线性方程组模板)

知道了是高斯消元后,其实只要稍加处理,就可以解决带模的情况. 1 是在进行矩阵行变化的时候,取模. 2 最后的除法用逆元.(因为a[i][i]必定非0 且小于模数) 然后对于无穷多解的情况,只需要将那些列全为0的未知数定义一个固定值.(这里设的是0)其余操作不变. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath&g

POJ.2065.SETI(高斯消元 模线性方程组)

题目链接 http://blog.csdn.net/Clove_unique/article/details/54381675 http://blog.csdn.net/u013081425/article/details/24299047 http://blog.csdn.net/lin375691011/article/details/38406737 https://www.cnblogs.com/IMGavin/p/5933037.html /* 模意义下的高斯消元,在初等行变换时把k=

2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)

题目链接 题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的那个去做,问她最终有一个账号达到1000分需要做的比赛的次数的期望值. 思路 :可以直接用公式推出来用DP做,也可以列出210个方程组用高斯消元去做. (1)DP1:离散化.因为50,100,1000都是50的倍数,所以就看作1,2,20.这样做起来比较方便. 定义dp[i]为从 i 分数到达i+1

ACM学习历程—HDU 3949 XOR(xor高斯消元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 题目大意是给n个数,然后随便取几个数求xor和,求第k小的.(重复不计算) 首先想把所有xor的值都求出来,对于这个规模的n是不可行的. 然后之前有过类似的题,求最大的,有一种方法用到了线性基. 那么线性基能不能表示第k大的呢? 显然,因为线性基可以不重复的表示所有结果.它和原数组是等价的. 对于一个满秩矩阵 100000 010000 001000 000100 000010 000001

lydsy1013: [JSOI2008]球形空间产生器sphere 高斯消元

题链:http://www.lydsy.com/JudgeOnline/problem.php?id=1013 1013: [JSOI2008]球形空间产生器sphere 时间限制: 1 Sec  内存限制: 162 MB 提交: 3063  解决: 1607 [提交][][] 题目描述 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器. 输入 第一行

【BZOJ 1013】【JSOI2008】球形空间产生器sphere 高斯消元基础题

最基础的高斯消元了,然而我把j打成i连WA连跪,考场上再犯这种错误就真的得滚粗了. #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) f

BZOJ 1013 JSOI2008 球形空间产生器sphere 高斯消元

题目大意:给定n维空间下的n+1个点,求这n个点所在的球面的球心 曾经尝试了很久的模拟退火0.0 至今仍未AC 0.0 今天挖粪涂墙怒学了高斯消元-- 我们设球心为X(x1,x2,...,xn) 假设有两点A(a1,a2,...,an)和B(b1,b2,...,bn) 那么我们可以得到两个方程 (x1-a1)^2+(x2-a2)^2+...+(xn-an)^2=r^2 (x1-b1)^2+(x2-b2)^2+...+(xn-bn)^2=r^2 这些方程都是二次的,无法套用高斯消元 但是我们可以做

[BZOJ1013] [JSOI2008] 球形空间产生器sphere (高斯消元)

Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器. Input 第一行是一个整数n(1<=N=10).接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标.每一个实数精确到小数点后6位,且其绝对值都不超过20000. Output 有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开.每个实数精确到

HDU3571 N-dimensional Sphere(高斯消元 同模方程)

每个点到中心距离相等,以第0个点为参考,其他n个点到中心距等于点0到中心距,故可列n个方程 列出等式后二次未知数相消,得到线性方程组 将每个数加上1e17,求答案是再减去,求解时对一个2 * (1e17)以上的一个素数取模. 可用java 中高精度  System.out.println(BigInteger.valueOf(200000000000000001L).nextProbablePrime())  求一个大于2 * (1e17)的质数. #include<cstdio> #incl