N-dimensional Sphere
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 670 Accepted Submission(s): 235
Problem Description
In an N-dimensional space, a sphere is defined as {(x1, x2 ... xN)| ∑(xi-Xi)^2 = R^2 (i=1,2,...,N) }. where (X1,X2…XN) is the center. You're given N + 1 points on an N-dimensional sphere and are asked to calculate the center of the sphere.
Input
The first line contains an integer T which is the number of test cases.
For each case there's one integer N on the first line.
Each of the N+1 following lines contains N integers x1, x2 ... xN describing the coordinate of a point on the N-dimensional sphere.
(0 <= T <= 10, 1 <= N <= 50, |xi| <= 10^17)
For each case there's one integer N on the first line.
Each of the N+1 following lines contains N integers x1, x2 ... xN describing the coordinate of a point on the N-dimensional sphere.
(0 <= T <= 10, 1 <= N <= 50, |xi| <= 10^17)
Output
For the kth case, first output a line contains “Case k:”, then output N integers on a line indicating the center of the N-dimensional sphere
(It's guaranteed that all coordinate components of the answer are integers and there is only one solution and |Xi| <= 10^17)
(It's guaranteed that all coordinate components of the answer are integers and there is only one solution and |Xi| <= 10^17)
Sample Input
2 2 1 0 -1 0 0 1 3 2 2 3 0 2 3 1 3 3 1 2 4
Sample Output
Case 1: 0 0 Case 2: 1 2 3
Author
stephydx
Source
题目分析:
方程很好求,就是n+1个方程,然后相减,去掉二次项,然后就是利用高斯消元求解,蛋疼的java超时了,然后参照别人的代码用移位乘法做的,过了,主要就是利用同余模定理,因为最后结果给定了范围,所以只需要对2*10^17+3取模,保证是个质数,因为要利用拓展欧几里得求逆元来做除法,然后套到高斯消元的模板当中,高斯消元很简单,就是行列式阶梯型化简,然后再递次向上求解
方程很好求,就是n+1个方程,然后相减,去掉二次项,然后就是利用高斯消元求解,蛋疼的java超时了,然后参照别人的代码用移位乘法做的,过了,主要就是利用同余模定理,因为最后结果给定了范围,所以只需要对2*10^17+3取模,保证是个质数,因为要利用拓展欧几里得求逆元来做除法,然后套到高斯消元的模板当中,高斯消元很简单,就是行列式阶梯型化简,然后再递次向上求解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define MAX 55
#define mod 200000000000000003LL
#define diff 100000000000000000LL
using namespace std;
int n;
typedef long long LL;
LL x[MAX] , g[MAX][MAX] , a[MAX][MAX] , b[MAX][MAX];
LL Mod ( LL x )
{
if ( x >= mod )
return x-mod;
return x;
}
LL mul ( LL a , LL b )
{
LL ret;
for ( ret = 0 ; b ; b >>= 1 )
{
if ( b&1 ) ret = Mod ( ret + a );
a = Mod ( a+a );
}
return ret;
}
void exgcd ( LL a , LL b , LL& d , LL& x , LL& y )
{
if ( !b )
x = 1 , y = 0 , d = a;
else
exgcd ( b , a%b , d , y , x ) , y -= (a/b)*x;
}
LL inv ( LL a , LL n )
{
LL x,y,d;
exgcd ( a , n , d , x , y );
return (x%n+n)%n;
}
void Gauss ()
{
int i,j,k;
LL v,temp;
for ( i = 0 ; i < n ; i++ )
{
for ( j = i ; j < n ; j++ )
{
if ( g[j][i] ) break;
}
if ( i != j )
for ( k = i ; k <= n ; k++ )
swap ( g[i][k] , g[j][k] );
v = inv ( g[i][i] , mod );
for ( j = i+1 ; j < n ; j++ )
{
if ( g[j][i] )
{
temp = mul ( g[j][i],v );
for ( k = i ; k <= n ; k++ )
{
g[j][k]-=mul(temp,g[i][k]);
g[j][k] = ( g[j][k]%mod+mod)%mod;
}
}
}
}
for ( i = n-1 ; i >= 0 ; i-- )
{
temp = 0;
for ( j = i+1 ; j < n ; j++ )
{
temp += mul ( x[j] , g[i][j] );
if ( temp >= mod ) temp -= mod;
}
temp = g[i][n] - temp;
temp =(temp%mod+mod)%mod;
x[i] = mul ( temp , inv ( g[i][i] , mod ) );
}
}
int main ( )
{
int t,c=1;
LL temp;
scanf ( "%d" , &t );
while ( t-- )
{
scanf ( "%d" , &n );
memset ( g , 0 , sizeof ( g ) );
memset ( b , 0 , sizeof ( b ) );
for ( int i = 0 ; i <= n ; i++ )
for ( int j = 0 ; j < n ; j++ )
{
scanf ( "%lld" , &a[i][j] );
a[i][j] += diff;
b[i][n] += mul(a[i][j],a[i][j]);
if ( b[i][n] >= mod ) b[i][n] -= mod;
}
for ( int i = 0 ; i < n ; i++ )
{
for ( int j = 0 ; j < n ; j++ )
{
temp = a[i+1][j] - a[i][j];
temp = ( temp%mod+mod)%mod;
g[i][j] = mul ( temp , 2 );
}
g[i][n] = b[i+1][n] - b[i][n];
g[i][n] = (g[i][n]%mod+mod)%mod;
}
Gauss();
printf ( "Case %d:\n", c++ );
printf ( "%lld" , x[0]-diff );
for ( int i = 1 ; i < n ; i++ )
printf ( " %lld" , x[i]-diff );
printf ( "\n" );
}
}