题意:问n+1个n维点的球心,即其他点到该点距离相等
    设距离为R,很容里列出n+1个方程,但是有2次项,只要下一行减上一行即可
    得到一个n个方程n个未知数,用高斯消元
    
    矩阵为
    A[i][j] = (V[i+1][j] - V[i][j])*2
    A[i][n+1] = V[i+1][j]^2 - V[i][j]^2  (只是增广的那一项)

    会超long long  但用java高精度会超时!
    1 <= N <= 50, |xi| <= 10^17  而且答案是整数解且 |Xi| <= 10^17
    只要运算过程中取模一个大于 2*10^17的素数即可
    Ax = B  
    => Ax %p = B %p
    => A%p x = B %p 
    即原方程的解等价于系数为A%p的方程的解

    注意:
    由于答案可以是负数,%p的话结果是[0,p),不对
    所以一开始对所有坐标都平移一下,都加上10^17,最后答案减去10^17即正确了

    看http://www.cppblog.com/AmazingCaddy/archive/2010/08/25/124608.html

   
    他这种是对row这一行都除以A[row][row]使得A[row][row]为1,很快
    由于取余,所以可以直接除(乘以逆元),不怕整不整除问题!!
ps: hdu 3571 高斯消元 取余 不能用高精度 
求逆元是用了费马小定理,很强悍啊。。。
即:若p是素数,a与p互素,则
a^(p-1)≡1(mod p)。。。。。。

*/Accepted3571390MS308K2758 B
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>using namespace std;const long long mod = 1000000000000000003LL;const long long INF = 100000000000000000LL;const int MAXN = 60;typedef long long ll;long long v[MAXN][MAXN];long long a[MAXN][MAXN];inline ll imod(ll a){    return (a%mod+mod)%mod;}inline ll iabs(ll a){    return a>0?a:-a;}inline ll imul(ll a,ll b){    ll ans=0,n=iabs(b);    while(n)    {        if(n&1)        {            ans+=a;            if(ans>=mod)这里优化很重要,如果直接写成ans=imod(ans);直接TLE。。。            ans-=mod;        }        a<<=1;        if(a>=mod)        a-=a;        n>>=1;    }    if(b<0)    ans=imod(-ans);    return ans;}inline ll ipow(ll a,ll b){    if(b==1)return a%mod;    ll ans=ipow(a,b>>1);    ans=imul(ans,ans);    if(b&1)    ans=imul(ans,a);    return ans;}inline ll inv(ll a){    return ipow(a,mod-2);}void printA(int n){    for(int i=0;i<n;i++)    {        for(int j=0;j<=n;j++)        printf("%I64d ",a[i][j]);        printf("\n");    }}void getA(int n){    for(int i=0;i<n;i++)    {        a[i][n]=0;        for(int j=0;j<n;j++)        {            a[i][j]=imod((v[i+1][j]-v[i][j])*2);            a[i][n]=imod(a[i][n]+imul(v[i+1][j],v[i+1][j])-imul(v[i][j],v[i][j]));           //printf("a[%d][j]=%I64d\n",i,a[i][j]);        }    }    //printA(n);}void gauss(int n){    int k,col,max,j,i,id;    for(k=0;k<n;k++)    {        max=a[k][k];id=k;        for(i=k+1;i<n;i++)        {            if(max<a[i][k])            {                max=a[i][k];                id=i;            }        }        if(id!=k)        {            for(i=k;i<=n;i++)            swap(a[k][i],a[id][i]);        }        ll div=inv(a[k][k]);//使得A[row][row] = 1;利用费马小定理        for(j=k+1;j<=n;j++)        {          a[k][j]=imul(a[k][j],div);//由于取余,所以可以直接除(乘以逆元),不怕整不整除问题!!          for(i=k+1;i<n;i++)          {              a[i][j]=imod(a[i][j]-imul(a[k][j],a[i][k]));          }        }    }    for(i=n-1;i>=0;i--)    {        for(j=n-1;j>i;j--)        {            a[i][n]=imod(a[i][n]-imul(a[i][j],a[j][j]));        }        a[i][i]=a[i][n];    }}void print(int n){    printf("%I64d",a[0][0]-INF);    for(int i=1;i<n;i++)    {       printf(" %I64d",a[i][i]-INF);    }    printf("\n");}int main(){    int t,cas=1,i,j,n;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=0;i<=n;i++)        for(j=0;j<n;j++)        {            scanf("%I64d",&v[i][j]);            v[i][j]+=INF;//平移一下,这样答案才是正确的        }        getA(n);        gauss(n);        printf("Case %d:\n",cas++);        print(n);    }    return 0;}