洛谷 CF429D Tricky Function

洛谷 CF429D Tricky Function

topic:

  • English. Turn link

answer:

  • People topic is intended to:
  • Given sequence a [1], a [2], ..., [n] a
  • Function f (i, j) = (i - j) ^ 2 + (a [i + 1] + a [i + 2] + ... + a [j]) ^ 2
  • Minimization of f. n ≤ 100000

  • Provided SUM [] to a [] array and prefix.
  • Then f (i, j) can be rewritten as f (i, j) = (i - j) ^ 2 + (sum [j] - sum [i]) ^ 2
  • This, not that distance formula it?
  • That point square of the distance (i, sum [i]) and the point (j, sum [j]) of.
  • So this question is transformed n points on the plane became, find the nearest point pair.

  • It is worth noting that the partition will find the nearest point on the T. That is
for(int i = l; i <= r; i++)
    {
        int v = a[i].x - a[mid].x;
        if(v < d)
            t[++cnt] = i;
    }
sort(t + 1, t + 1 + cnt, cmp2);
for(int i = 1; i < cnt; i++)
    for(int j = i + 1; j <= cnt; j++)
    {
        int v = a[t[j]].y - a[t[i]].y;
        if(v >= d) break;
        else d = min(d, cal(t[i], t[j]));
    }
  • This piece of code must be changed as follows, to A out.
for(int i = l; i <= r; i++)
    {
        int v = a[i].x - a[mid].x;
        if(v * v < d) //改动了这里
            t[++cnt] = i;
    }
sort(t + 1, t + 1 + cnt, cmp2);
for(int i = 1; i < cnt; i++)
    for(int j = i + 1; j <= cnt; j++)
    {
        int v = a[t[j]].y - a[t[i]].y;
        if(v * v >= d) break; //改动了这里
        else d = min(d, cal(t[i], t[j]));
    }
  • Personally I think that change is not plausible in principle.
  • How correctness too konjac after changes do not understand the proof.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define N 100005
#define inf 0x7fffffff
#define int long long
using namespace std;

struct A {int x, y;} a[N];
int sum[N], t[N];
int n;

int read()
{
    int x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x *= f;
}

bool cmp1(A u, A v) {return u.x < v.x;}
bool cmp2(int u, int v) {return a[u].y < a[v].y;}

int cal(int u, int v)
{
    int v1 = (a[u].x - a[v].x) * (a[u].x - a[v].x);
    int v2 = (a[u].y - a[v].y) * (a[u].y - a[v].y);
    return v1 + v2;
}

int fun(int l, int r)
{
    if(l == r) return inf;
    if(l + 1 == r) return cal(l, r);
    int mid = (l + r) >> 1, cnt = 0;
    int d = min(fun(l, mid), fun(mid + 1, r));
    for(int i = l; i <= r; i++)
    {
        int v = a[i].x - a[mid].x;
        if(v * v < d)
            t[++cnt] = i;
    }
    sort(t + 1, t + 1 + cnt, cmp2);
    for(int i = 1; i < cnt; i++)
        for(int j = i + 1; j <= cnt; j++)
        {
            int v = a[t[j]].y - a[t[i]].y;
            if(v * v >= d) break;
            else d = min(d, cal(t[i], t[j]));
        }
    return d;
}

signed main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int val = read();
        sum[i] = sum[i - 1] + val;
        a[i].x = i, a[i].y = sum[i];
    }
    sort(a + 1, a + 1 + n, cmp1);
    cout << fun(1, n);
    return 0;
}

Guess you like

Origin www.cnblogs.com/BigYellowDog/p/11628318.html