二分答案,对于每个点求出满足的区域,求出这些区域的交。一个区域可以表示成:
...≤x+y+z≤...
.
.
.
≤
x
+
y
+
z
≤
.
.
.
...≤x+y−z≤...
.
.
.
≤
x
+
y
−
z
≤
.
.
.
...≤x−y+z≤...
.
.
.
≤
x
−
y
+
z
≤
.
.
.
...≤−x+y+z≤...
.
.
.
≤
−
x
+
y
+
z
≤
.
.
.
设 a=x+y−z,b=x−y+z,c=−x+y+z a = x + y − z , b = x − y + z , c = − x + y + z ,则
a+b+c=x+y+z
a
+
b
+
c
=
x
+
y
+
z
x=a+b2
x
=
a
+
b
2
y=a+c2
y
=
a
+
c
2
z=b+c2
z
=
b
+
c
2
所以 a,b,c a , b , c 的奇偶性必须相同。然后将 a,b,c a , b , c 增大,使其满足第一个条件就好了。
#include<bits/stdc++.h>
using namespace std;
inline char nc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
char c=nc(),b=1;
for(;c<'0'||c>'9';c=nc())if(c=='-')b=-1;
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());x*=b;
}
typedef long long ll;
inline void Read(ll& x){
char c=nc(),b=1;
for(;c<'0'||c>'9';c=nc())if(c=='-')b=-1;
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());x*=b;
}
const int N=100010;
int T;
int k,n,m;
ll a[N],b[N],c[N];
ll Ans1,Ans2,Ans3;
ll L[4],R[4];
inline bool Check(ll x){
for(int i=0;i<4;i++)L[i]=-9e18,R[i]=9e18;
for(int i=1;i<=n;i++){
ll A=a[i],B=b[i],C=c[i];
L[0]=max(L[0],A+B+C-x);R[0]=min(R[0],A+B+C+x);
L[1]=max(L[1],A+B-C-x);R[1]=min(R[1],A+B-C+x);
L[2]=max(L[2],A-B+C-x);R[2]=min(R[2],A-B+C+x);
L[3]=max(L[3],-A+B+C-x);R[3]=min(R[3],-A+B+C+x);
}
for(int d=0;d<2;d++){
ll a=L[1],b=L[2],c=L[3],e=L[0],A=R[1],B=R[2],C=R[3],E=R[0];
if((a&1)!=d)a++;if((A&1)!=d)A--;
if((b&1)!=d)b++;if((B&1)!=d)B--;
if((c&1)!=d)c++;if((C&1)!=d)C--;
if((e&1)!=d)e++;if((E&1)!=d)E--;
if(a>A||b>B||c>C||e>E||a+b+c>E||A+B+C<e)continue;
ll cur=max(e-a-b-c,0ll),t;
t=min(cur,A-a);
a+=t;cur-=t;
t=min(cur,B-b);
b+=t;cur-=t;
t=min(cur,C-c);
c+=t;cur-=t;
if(cur)continue;
Ans1=(a+b)/2;Ans2=(a+c)/2;Ans3=(b+c)/2;
return 1;
}
return 0;
}
int main(){
Read(T);
while(T--){
Read(n);
for(int i=1;i<=n;i++)Read(a[i]),Read(b[i]),Read(c[i]);
ll l=0,r=3e18;
while(l<=r){
ll Mid=l+r>>1;
if(Check(Mid))r=Mid-1;else l=Mid+1;
}
printf("%I64d %I64d %I64d\n",Ans1,Ans2,Ans3);
}
}