抢了个一血。不懂啊,这么傻逼的题居然没有人在 52 min 52 \min 52min 内切(我如果小细节不写挂就十分钟切了)。
题目描述
给你若干个三元组 ( a i , b i , c i ) (a_i,b_i,c_i) (ai,bi,ci) 和 ( a i ′ , b i ′ , c i ′ ) (a_i',b_i',c_i') (ai′,bi′,ci′)。
你可以从 ( a i , b i , c i ) (a_i,b_i,c_i) (ai,bi,ci) 和 ( a i ′ , b i ′ , c i ′ ) (a_i',b_i',c_i') (ai′,bi′,ci′) 中选择一个三元组作为第 i i i 个三元组( a i ′ ≥ a i , b i ′ ≥ b i , c i ′ ≥ c i a_i' \ge a_i,b_i' \ge b_i,c_i' \ge c_i ai′≥ai,bi′≥bi,ci′≥ci)。
设你最后选择的三元组是 ( A i , B i , C i ) (A_i,B_i,C_i) (Ai,Bi,Ci)。
那么这种方案的权值就是 max ( max A i − min A i , max B i − min B i , max C i − min C i ) \max(\max A_i-\min A_i,\max B_i - \min B_i,\max C_i- \min C_i) max(maxAi−minAi,maxBi−minBi,maxCi−minCi)。
你需要找出一种方案,使得权值最小,并输出最小权值。
思路
看到最大值最小,直接二分。
考虑如何 c h e c k \rm check check。
我们把 ( a i , b i , c i ) (a_i,b_i,c_i) (ai,bi,ci) 和 ( a i ′ , b i ′ , c i ′ ) (a_i',b_i',c_i') (ai′,bi′,ci′) 并成一个六元组 ( a i , b i , c i , a i ′ , b i ′ , c i ′ ) (a_i,b_i,c_i,a_i',b_i',c_i') (ai,bi,ci,ai′,bi′,ci′),先钦定所有三元组都选 ( a i , b i , c i ) (a_i,b_i,c_i) (ai,bi,ci)。
搞三个数组: x , y , z x,y,z x,y,z,分别表示这个六元组按 a i a_i ai 排序,按 b i b_i bi 排序,按 c i c_i ci 排序后的结果。
不难发现需要换成 ( a i ′ , b i ′ , c i ′ ) (a_i',b_i',c_i') (ai′,bi′,ci′) 的三元组一定是 x , y , z x,y,z x,y,z 的一段前缀。
三个指针扫一遍即可。
注意需要判断前面三元组换了之后还是不满足条件的情况。
时间复杂度 O ( n log n ) \mathcal O(n \log n) O(nlogn)。
代码
//A tree without skin will surely die.
//A man without face is invincible.
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define sqr(x) ((x)*(x))
#define all(x) (x).begin(),(x).end()
#define Tim ((double)clock()/CLOCKS_PER_SEC)
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
int const N=1e5+10;
int n,nwx,nwy,nwz,ix,iy,iz,qza,qzb,qzc;
struct node{int a,b,c,d,e,f;}a[N],b[N],c[N];
void push(node x){
nwx=max(nwx,x.d),nwy=max(nwy,x.e),nwz=max(nwz,x.f);
qza=min(qza,x.d),qzb=min(qzb,x.e),qzc=min(qzc,x.f);
}
bool check(int V){
nwx=a[n].a,nwy=b[n].b,nwz=c[n].c,ix=1,iy=1,iz=1,qza=1e9,qzb=1e9,qzc=1e9;
while (1){
if (nwx-a[ix].a<=V && nwy-b[iy].b<=V && nwz-c[iz].c<=V && nwx-qza<=V && nwy-qzb<=V && nwz-qzc<=V) return 1;
while (ix<=n && nwx-a[ix].a>V){push(a[ix]),++ix;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
while (iy<=n && nwy-b[iy].b>V){push(b[iy]),++iy;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
while (iz<=n && nwz-c[iz].c>V){push(c[iz]),++iz;if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;}
if (nwx-qza>V || nwy-qzb>V || nwz-qzc>V) return 0;
}
return 1;
}
void solve(){
cin>>n;
for (int i=1;i<=n;++i) cin>>a[i].a>>a[i].b>>a[i].c>>a[i].d>>a[i].e>>a[i].f;
for (int i=1;i<=n;++i) b[i]=a[i],c[i]=a[i];
sort(a+1,a+n+1,[](node x,node y){return x.a<y.a;});
sort(b+1,b+n+1,[](node x,node y){return x.b<y.b;});
sort(c+1,c+n+1,[](node x,node y){return x.c<y.c;});
int l=0,r=1e9;
while (l<r)
if (check(mid)) r=mid;
else l=mid+1;
cout<<l<<'\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t=1;
cin>>t;
while (t--) solve();
return 0;
}