Codeforces 1179 D - Fedor Runs for President

D - Fedor Runs for President

思路:

推出斜率优化公式后,会发现最优点只可能来自凸斜率中的第一个元素和最后一个元素,

这两个元素不用维护凸斜率也能知道,就是第一个和上一个元素

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb emplace_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head 

const int N = 5e5 + 5;
vector<int> g[N];
int n, u, v, sz[N];
LL dp[N], ans;
//(dp[j]-dp[k]+sz[j]^2-sz[k]^2)/(sz[j]-sz[k]) >= 2*(n-sz[i]) k < j
bool _g(int k, int j, LL C) {
    return (dp[j]-dp[k]+sz[j]*1LL*sz[j]-sz[k]*1LL*sz[k]) <= C*(sz[j]-sz[k]);
}
//(dp[i]-dp[j]+sz[i]^2-sz[j]^2)/(sz[i]-sz[j]) >= (dp[j]-dp[k]+sz[j]^2-sz[k]^2)/(sz[j]-sz[k])
//k < j < i
bool gg(int k, int j, int i) {
    return (dp[i]-dp[j]+sz[i]*1LL*sz[i]-sz[j]*1LL*sz[j])*(sz[j]-sz[k]) <= (dp[j]-dp[k]+sz[j]*1LL*sz[j]-sz[k]*1LL*sz[k])*(sz[i]-sz[j]);
}
void dfs(int u, int o) {
    sz[u] = 1;
    for (int v : g[u]) {
        if(v != o) {
            dfs(v, u);
            ans = min(ans, (n-sz[v])*1LL*(n-sz[v]) + sz[v]*1LL*sz[v]);
            sz[u] += sz[v];
        }
    }
    dp[u] = sz[u]*1LL*sz[u];
    for (int v : g[u]) {
        if(v != o) {
            dp[u] = min(dp[u], (sz[u]-sz[v])*1LL*(sz[u]-sz[v])+dp[v]);
        }
    }
    sort(g[u].begin(), g[u].end(), [](int x, int y){
            return sz[x] > sz[y];
         });
    int l = -1, r = -1;
    for (int v : g[u]) {
        if(v == o) continue;
        if(l == -1) {
            l = r = v;
            continue;
        }
        int x = l;
        ans = min(ans, dp[v]+dp[x]+(n-sz[v]-sz[x])*1LL*(n-sz[v]-sz[x]));
        x = r;
        ans = min(ans, dp[v]+dp[x]+(n-sz[v]-sz[x])*1LL*(n-sz[v]-sz[x]));
        r = v;
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i < n; ++i) scanf("%d %d", &u, &v), g[u].pb(v), g[v].pb(u);
    int rt = 1;
    for (int i = 1; i <= n; ++i) if(g[i].size() != 1) rt = i;
    ans = n*1LL*n;
    dfs(rt, rt);
    printf("%lld\n", n*1LL*(n-1) - (ans-n)/2);
    return 0;
}

 

posted @ 2019-07-09 13:13  Wisdom+.+  阅读(261)  评论(0编辑  收藏  举报