zoukankan      html  css  js  c++  java
  • 洛谷 CF429D Tricky Function(平面最近点对,分治)

    传送门


    解题思路

    首先看g函数的求法,很显然是个前缀和,于是题目就变成了求(i-j)^2+(s[i]-s[j])^2的最小值,所以就变成了求平面最近点对。

    注意这里没有根号,为此还sb般地询问了Candy?大佬。

    然后分治求一下就ok了。

    欣赏一下cf强大的测试数据吧(满满的全是绿色):

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<vector>
    11 #include<iomanip>
    12 #include<ctime>
    13 #include<stack>
    14 using namespace std;
    15 const int maxn=100005;
    16 struct node{
    17     long long x,y;
    18 }p[maxn],q[maxn];
    19 bool cmp(const node &a,const node &b){
    20     return a.x<b.x;
    21 }
    22 long long dis(const node &a,const node &b){
    23     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    24 }
    25 int n,a[maxn];
    26 long long divide(int l,int r){
    27     if(l==r){
    28         return 1LL<<60;
    29     }
    30     int mid=(l+r)>>1,p1=l,p2=mid+1,tot=0;
    31     int midx=p[mid].x;
    32     long long d=min(divide(l,mid),divide(mid+1,r));
    33     while(p1<=mid||p2<=r){
    34         if(p1<=mid&&(p2>r||p[p1].y<p[p2].y)){
    35             q[++tot]=p[p1++];
    36         }else{
    37             q[++tot]=p[p2++];
    38         }
    39     }
    40     for(int i=1;i<=tot;i++){
    41         p[l+i-1]=q[i];
    42     }
    43     tot=0;
    44     for(int i=l;i<=r;i++){
    45         if((p[i].x-midx)*(p[i].x-midx)<=d){
    46             q[++tot]=p[i];
    47         }
    48     }
    49     for(int i=1;i<=tot;i++){
    50         for(int j=i-1;j>0&&(q[i].y-q[j].y)*(q[i].y-q[j].y)<=d;j--){
    51             d=min(d,dis(q[i],q[j]));
    52         }
    53         for(int j=i+1;j<=tot&&(q[j].y-q[i].y)*(q[j].y-q[i].y)<=d;j++){
    54             d=min(d,dis(q[i],q[j]));
    55         }
    56     }
    57     return d;
    58 }
    59 int main()
    60 {
    61     cin>>n;
    62     for(int i=1;i<=n;i++){
    63         scanf("%d",&a[i]);
    64         p[i].x=i;
    65         p[i].y=p[i-1].y+a[i];
    66     }
    67     sort(p+1,p+n+1,cmp);
    68     cout<<divide(1,n)<<endl; 
    69     return 0;
    70 }
  • 相关阅读:
    满巢尽洒英雄泪
    谋略的原则——经商就是讲谋略的交易
    杨文军(为奥运冠军名字作诗)
    邹市明 (为奥运冠军名字作诗)
    王励勤 (为奥运冠军名字作诗)
    想成功创业:要掌握“三笔钱”和“六三一”原则
    王丽萍(再帮别人名字作诗)
    陆春龙(为奥运冠军名字作诗)
    殷剑 (为奥运冠军名字作诗)
    孟关良(为奥运冠军名字作诗)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12311139.html
Copyright © 2011-2022 走看看