CF685C Optimal Point
CF685C
在一個三維空間中有若干個點。
你要找到一個整點使得它與若干個整點的曼哈頓距離最大值最小。
n ≤ 1 0 5 n\le 10^5 n≤105
坐 標 ≤ 1 0 18 座標\le 10^{18} 坐標≤1018
簡單題+調半天
首先可以類比二維平面的曼哈頓距離和切比雪夫距離的轉化: ( x , y ) (x,y) (x,y)到原點的曼哈頓距離為 ∣ x ∣ + ∣ y ∣ |x|+|y| ∣x∣+∣y∣,切比雪夫距離為 m a x ( ∣ x ∣ , ∣ y ∣ ) max(|x|,|y|) max(∣x∣,∣y∣)。那麼 ( x , y ) (x,y) (x,y)到原點的曼哈頓距離相當於 ( x + y , x − y ) (x+y,x-y) (x+y,x−y)到原點的切比雪夫距離。具體的推法考慮 ∣ x ∣ = m a x ( x , − x ) |x|=max(x,-x) ∣x∣=max(x,−x),分類討論將四種情況寫出來求最大值,發現可以用切比雪夫距離來表示。
但放到三維,曼哈頓距離為 ∣ x ∣ + ∣ y ∣ + ∣ z ∣ |x|+|y|+|z| ∣x∣+∣y∣+∣z∣。這個東西實際上不能轉化成切比雪夫距離。但這個套路還可以利用:根據每一維的正負號分成八類,然後這個點可以從三維空間對映到一個四維空間。
形象地說,原點一定距離以內的點形成一個八面體。然後每個平面形如 x + y + z = d x+y+z=d x+y+z=d或 x + y − z = d x+y-z=d x+y−z=d這種形式。
顯然這題要二分答案,二分答案之後求這些八面體的交集。
將它對映到的四維空間求個交集,於是就得到了 x + y + z , x + y − z , x − y + z , x − y − z 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=x+y−z,b=x−y+z,c=x−y−z,那麼有 x + y + z = a + b − c x+y+z=a+b-c x+y+z=a+b−c, x = a + b 2 , y = a − c 2 , z = b − c 2 x=\frac{a+b}{2},y=\frac{a-c}{2},z=\frac{b-c}{2} x=2a+b,y=2a−c,z=2b−c
問題變成了:找到 a , b , c a,b,c a,b,c滿足 a ≡ b ≡ c ( m o d 2 ) a\equiv b\equiv c \pmod 2 a≡b≡c(mod2), a + b − c , a , b , c a+b-c,a,b,c a+b−c,a,b,c在各自的範圍內。
前面這個同餘的性質好做,列舉餘數 r r r,然後將 a a a對映到 a − r 2 \frac{a-r}{2} 2a−r,相應的區間也改一下。
後面的重點是要讓 a + b − c a+b-c a+b−c在範圍內。先讓 a , b , c a,b,c a,b,c取到最小值,如果不滿足 a + b − c a+b-c a+b−c的限制,那麼把 a a a調大,不行就再把 b b b調大,還不行就再把 c c c調小。由於通過這種方式我們得到的 a + b − c a+b-c a+b−c的值是連續的,所以如果找不到一定無解。
細節有點多。。。(還有吐槽一下座標開到
1
0
18
10^{18}
1018,二分範圍
6
∗
1
0
18
6*10^{18}
6∗1018,直接打mid=l+r>>1
會掛的。。。解決的話可以開ull
或者寫mid=l+(r-l>>1)
)
以下的程式碼有非常多得到除錯語句,所以顯得特別長。。。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <climits>
#define N 100010
#define ll long long
#define ull unsigned long long
int n;
struct DOT{long long x[3];} d[N],ans;
bool in(ll x,ll l,ll r){return l<=x && x<=r;}
ll m[8],m_[8];
void calc(ll a,ll b,ll c,ll r){
a=2*a+r,b=2*b+r,c=2*c+r;
assert(m[0]<=a+b-c && a+b-c<=m[4]);
ans.x[0]=a+b>>1;
ans.x[1]=a-c>>1;
ans.x[2]=b-c>>1;
assert(in(a,m[1],m[5]));
assert(in(b,m[2],m[6]));
assert(in(c,m[3],m[7]));
}
bool judge(ll l){
for (int i=0;i<4;++i)
m[i]=LLONG_MIN,m[i+4]=LLONG_MAX;
for (int i=1;i<=n;++i){
for (int j=0;j<4;++j){
ll t=d[i].x[0];
for (int k=1;k<3;++k)
t+=d[i].x[k]*(j>>2-k&1?-1:1);
m[j]=max(m[j],t-l);
m[j+4]=min(m[j+4],t+l);
}
}
for (int i=0;i<4;++i)
if (m[i]>m[i+4])
return 0;
// for (int i=0;i<4;++i)
// cout<<(long double)m[i]<<" "<<(long double)m[i+4]<<endl;
// printf("%.0lf %.0lf\n",(double)m[i],(double)m[i+4]);
for (int r=0;r<=1;++r){
bool cant=0;
for (int i=0;i<4;++i){
m_[i]=(m[i]-r)+1>>1;
m_[i+4]=(m[i+4]-r)>>1;
if (m_[i]>m_[i+4])
cant=1;
}
if (cant) continue;
// for (int i=0;i<4;++i)
// cout<<(long double)m[i]<<" "<<(long double)m[i+4]<<endl;
// printf("%.0lf %.0lf\n",(double)m_[i],(double)m_[i+4]);
ll a=m_[1],b=m_[2],c=m_[7];
// printf("%.0lf\n",(double)a+b-c);
if (in(a+b-c,m_[0],m_[4])){
calc(a,b,c,r);
return 1;
}
ll t=m_[0]-(a+b-c);
// printf("%.0lf %.0lf\n",(double)a+b-c+t,(double)a+t);
if (in(a+t,m_[1],m_[5])){
calc(a+t,b,c,r);
return 1;
}
else
t-=m_[5]-a,a=m_[5];
// printf("%.0lf %.0lf\n",(double)a+b-c+t,(double)b+t);
if (in(b+t,m_[2],m_[6])){
calc(a,b+t,c,r);
return 1;
}
else
t-=m_[6]-b,b=m_[6];
// printf("%.0lf %.0lf\n\n",(double)a+b-c+t,(double)c-t);
if (in(c-t,m_[3],m_[7])){
calc(a,b,c-t,r);
return 1;
}
// a=m_[5],b=m_[6],c=m_[3];
// if (in(a+b-c,m_[0],m_[4])){
// calc(a,b,c,r);
// return 1;
// }
// t=(a+b-c)-m_[4];
// if (in(a-t,m_[1],m_[5])){
// calc(a-t,b,c,r);
// return 1;
// }
// if (in(b-t,m_[2],m_[6])){
// calc(a,b-t,c,r);
// return 1;
// }
// if (in(c+t,m_[3],m_[7])){
// calc(a,b,c+t,r);
// return 1;
// }
}
return 0;
}
int main(){
freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%lld%lld%lld",&d[i].x[0],&d[i].x[1],&d[i].x[2]);
// printf("%.0lf\n",(double)tmp);
ll l=0,r=6000000000000000000,res=-1;
// printf("%d\n",judge(r));
while (l<=r){
ll mid=(ull)l+(ull)r>>1;
if (judge(mid))
r=(res=mid)-1;
else
l=mid+1;
}
// printf("%lld\n",(long long)res);
judge(res);
ll tmp=0;
for (int i=1;i<=n;++i)
tmp=max(tmp,abs(ans.x[0]-d[i].x[0])+abs(ans.x[1]-d[i].x[1])+abs(ans.x[2]-d[i].x[2]));
// printf("%lld\n",tmp);
printf("%lld %lld %lld\n",ans.x[0],ans.x[1],ans.x[2]);
}
return 0;
}
相關文章
- study critical point and saddle point using Hessian Matrix
- SPOJ - OPTM Optimal Marks(進位制拆分+最小割)
- SampleNet: Differentiable Point Cloud SamplingCloud
- OpenCV(logPolar()、Point2f())OpenCV
- The APR based Apache Tomcat Native library which allows optimal performance in production ...解決方案ApacheTomcatORM
- 遷移學習(SOT)《Cross-domain Activity Recognition via Substructural Optimal Transport》遷移學習ROSAIStruct
- OpenCV(cv::Point、cv::Rect、cv::Mat)OpenCV
- Script of Narrative Writing from different point of viewView
- 不動點迭代(Fixed Point Iteration)
- PostgreSQL DBA(19) - REDO point淺析SQL
- 什麼是 bootstrap 中的 break pointboot
- Networking from the container's point of view 筆記AIView筆記
- Tekno Point的新CX開發中心揭幕
- Battle Point | 海哥說資料大屏BAT
- SAP QM 檢驗點 (Inspection Point) 的使用
- abc098D Xor Sum 2(two point)
- 點雲分割網路---Point Transformer V3ORM
- 點雲分割網路---Point Transformer V1ORM
- PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation3DSegmentation
- Using Geometry to Detect Grasp Poses in 3D Point Clouds3DCloud
- Amazon OA2 K-Nearest Point C++RESTC++
- IDEA Debug框的 show execution point按鈕沒了Idea
- The injection point has the following annotations: - @org.springframework.beans.factory.annotation.SpringFrameworkBean
- org.apache.coyote.AbstractProtocol.destroy Failed to destroy end point associated with ProtocolHandlApacheProtocolAI
- 知識表示學習 (一) —— Point-Wise Space之2
- JVM(三)----垃圾收集演算法及Safe Point介紹JVM演算法
- safe-point(safepoint 安全點) 和 safe-region(安全區域)
- SAP MM SPED輸出報錯-No authorization for delivery from shipping point US##-
- Check Point:單反相機已成為勒索軟體攻擊目標
- 【論文速遞】PolarNet: An Improved Grid Representation for Online LiDAR Point Clouds Semantic SegmentationCloudSegmentation
- Check Point創新性提出“3C”理念 全面賦能合作伙伴
- 為什麼我們需要給 Angular library 建立多重入口 multiple entry pointAngular
- 嚴重: Failed to destroy end point associated with ProtocolHandler ["ajp-nio-8009"] java.lang.NullPointAIProtocolJavaNull
- 網易成立海外新工作室Anchor Point Studios,約空缺100個崗位iOS
- 2020ICPC·小米 網路選拔賽熱身賽K-Random Point in Trianglerandom
- tomcat啟動出現錯誤:Failed to destroy end point associated with ProtocolHandler["ajp-nio-8009"]TomcatAIProtocol
- mysql point in time recovery using sql_thread SQL_Thread增量恢復binlog 要點MySqlthread
- 解決啟動Tomcat報錯:Failed to destroy end point associated with ProtocolHandler["ajp-nio-8009"]TomcatAIProtocol