LuoguP3964 [TJOI2013]松鼠聚会【切比雪夫距离/前缀和】
前置知识:切比雪夫距离和曼哈顿距离的相互转化--自为风月马前卒
有了这个知识,我们便可以在读入松鼠的家的坐标时,先把他转化一下,然后把最后的总式化简,我们会得到一个充满后缀和以及前缀和的式子,这里有十分详细的展开式。于是我们把$x$,$y$坐标分别排序并求出他们的前缀和即可。
之后我们枚举每个点,在这个点意义下求出答案,更新答案最小值。
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 typedef long long ll; 6 7 int n; 8 ll tmp,ans=1e16; 9 ll subx[100090],suby[100090]; 10 ll rx[100090],ry[100090]; 11 struct node{ 12 ll x,y; 13 }p[100090]; 14 15 ll check(int u) 16 { 17 int pos=0; 18 ll ax=0,ay=0; 19 pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx; 20 ax+=pos*p[u].x-subx[pos]; 21 ax+=subx[n]-subx[pos]-p[u].x*(n-pos); 22 pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry; 23 ay+=pos*p[u].y-suby[pos]; 24 ay+=suby[n]-suby[pos]-p[u].y*(n-pos); 25 return ax+ay; 26 } 27 28 int main() 29 { 30 scanf("%d",&n); 31 for(int i=1;i<=n;i++) 32 { 33 ll x=0,y=0; 34 scanf("%lld%lld",&x,&y); 35 rx[i]=x+y;ry[i]=x-y; 36 p[i].x=rx[i],p[i].y=ry[i]; 37 } 38 sort(rx+1,rx+1+n); 39 sort(ry+1,ry+1+n); 40 for(int i=1;i<=n;i++) 41 subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i]; 42 for(int i=1;i<=n;i++) 43 tmp=check(i),ans=min(ans,tmp); 44 printf("%lld",ans>>1); 45 return 0; 46 }
* 注意观察式子,在前缀和那里不要用错=w=...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 typedef long long ll; 6 7 int n; 8 ll tmp,ans=1e16; 9 ll subx[100090],suby[100090]; 10 ll rx[100090],ry[100090]; 11 struct node{ 12 ll x,y; 13 }p[100090]; 14 15 ll check(int u) 16 { 17 int pos=0; 18 ll ax=0,ay=0; 19 pos=lower_bound(rx+1,rx+1+n,p[u].x)-rx; 20 ax+=pos*p[u].x-subx[pos]; 21 ax+=subx[n]-subx[pos-1]-p[u].x*(n-pos); 22 pos=lower_bound(ry+1,ry+1+n,p[u].y)-ry; 23 ay+=pos*p[u].y-suby[pos]; 24 ay+=suby[n]-suby[pos-1]-p[u].y*(n-pos); 25 return ax+ay; 26 } 27 28 int main() 29 { 30 scanf("%d",&n); 31 for(int i=1;i<=n;i++) 32 { 33 ll x=0,y=0; 34 scanf("%lld%lld",&x,&y); 35 rx[i]=x+y;ry[i]=x-y; 36 p[i].x=rx[i],p[i].y=ry[i]; 37 } 38 sort(rx+1,rx+1+n); 39 sort(ry+1,ry+1+n); 40 for(int i=1;i<=n;i++) 41 subx[i]=subx[i-1]+rx[i],suby[i]=suby[i-1]+ry[i]; 42 for(int i=1;i<=n;i++) 43 tmp=check(i),ans=min(ans,tmp); 44 printf("%lld",ans>>1); 45 return 0; 46 }
独立意志与自由思想是必须争的,且须以生死力争。