题意:问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)。。。。。。

*/

Accepted 3571 390MS 308K 2758 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;
}