Codeforces

思路

考虑把连的那两个点中间的链提出来,那么就会变成一条链,链上的每个点挂着一棵子树的形式。

设那些子树的大小为\(S_1,S_2,\cdots\),那么新加的简单路径个数就是

\[\frac 1 2 (n^2-\sum S^2)
\]

很容易理解:任意两个点,只要不在同一棵子树内,就会多一条路径。

那么就可以树形DP:设\(dp_x\)表示从\(x\)向下连的一条链,\(\sum S^2\)的最小值,也很容易转移。

但是统计答案,也就是把两条链连在一起的时候,怎么办呢?

考虑合并\(x,y\)的链,他们的子树大小为\(size_x,size_y\),那么有

\[ans=dp_x+dp_y+(n-size_x-size_y)^2
\]

把括号拆开之后容易看出是一个斜率优化的形式,乱搞即可。

那么问题来了:这种题是怎么搞到难度2600的?

代码

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pil pair<int,ll>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 505050
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n;
struct hh{int t,nxt;}edge[sz<<1];
int head[sz],ecnt;
void make_edge(int f,int t)
{
edge[++ecnt]=(hh){t,head[f]};
head[f]=ecnt;
edge[++ecnt]=(hh){f,head[t]};
head[t]=ecnt;
} ll dp[sz];
int size[sz];
ll ans=1e18;
#define v edge[i].t
#define Sqr(x) (1ll*(x)*(x))
inline db K(pil a,pil b){return 1.0*(b.sec-a.sec)/(b.fir-a.fir);}
void dfs(int x,int fa)
{
vector<pil>V;size[x]=1;
go(x) if (v!=fa)
{
dfs(v,x);
V.push_back(MP(size[v],dp[v]-2ll*n*size[v]+Sqr(size[v])));
size[x]+=size[v];
}
dp[x]=Sqr(size[x]);
go(x) if (v!=fa) chkmin(dp[x],dp[v]+Sqr(size[x]-size[v]));
if (!V.size()) return;
sort(V.begin(),V.end());
vector<pil>con;con.push_back(V[0]);int top=0;
rep(i,1,(int)V.size()-1)
{
while (top&&K(con[top],con[top-1])>-2*V[i].fir) --top,con.pop_back();
chkmin(ans,con[top].sec+V[i].sec+2ll*con[top].fir*V[i].fir+Sqr(n));
if (V[i].fir==V[i-1].fir) continue;
while (top&&K(con[top],con[top-1])>=K(con[top-1],V[i])) --top,con.pop_back();
con.push_back(V[i]);++top;
}
} int main()
{
file();
int x,y;
read(n);
rep(i,1,n-1) read(x,y),make_edge(x,y);
dfs(1,0);chkmin(ans,dp[1]);
ll Ans=(Sqr(n)-ans)/2+1ll*n*(n-1)/2;
cout<<Ans;
return 0;
}

其他解法

参见 XZZ大佬的博客: https://www.cnblogs.com/xzz_233/p/11070827.html

并没有看懂他干了什么,可能有一些玄妙的结论……

CF1179D Fedor Runs for President [DP,斜率优化]的更多相关文章

  1. Codeforces 1179 D - Fedor Runs for President

    D - Fedor Runs for President 思路: 推出斜率优化公式后,会发现最优点只可能来自凸斜率中的第一个元素和最后一个元素, 这两个元素不用维护凸斜率也能知道,就是第一个和上一个元 ...

  2. 【BZOJ-4518】征途 DP + 斜率优化

    4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 230  Solved: 156[Submit][Status][ ...

  3. 【BZOJ-3437】小P的牧场 DP + 斜率优化

    3437: 小P的牧场 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 705  Solved: 404[Submit][Status][Discuss ...

  4. 【BZOJ-1010】玩具装箱toy DP + 斜率优化

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][St ...

  5. 【BZOJ】1096: [ZJOI2007]仓库建设(dp+斜率优化)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1096 首先得到dp方程(我竟然自己都每推出了QAQ)$$d[i]=min\{d[j]+cost(j+ ...

  6. BZOJ 1096: [ZJOI2007]仓库建设(DP+斜率优化)

    [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在 ...

  7. 学渣乱搞系列之dp斜率优化

    学渣乱搞系列之dp斜率优化 By 狂徒归来 貌似dp的斜率优化一直很难搞啊,尤其是像我这种数学很挫的学渣,压根不懂什么凸包,什么上凸下凸的,哎...说多了都是泪,跟wdd讨论了下,得出一些结论.本文很 ...

  8. DP斜率优化总结

    目录 DP斜率优化总结 任务安排1 任务计划2 任务安排3 百日旅行 DP斜率优化总结 任务安排1 首先引入一道题,先\(O(N^2)\)做法:分别预处理出\(T_i,C_i\)前缀和\(t[i],c ...

  9. HDU 3507 [Print Article]DP斜率优化

    题目大意 给定一个长度为\(n(n \leqslant 500000)\)的数列,将其分割为连续的若干份,使得 $ \sum ((\sum_{i=j}^kC_i) +M) $ 最小.其中\(C_i\) ...

随机推荐

  1. ORACLE PL/SQL 实例精解之第五章 条件控制:CASE语句

    5.1 CASE语句 1. CASE语句具有如下结构 CASE SELECTOR WHEN EXPRESSION 1 THEN STATEMENT 1; WHEN EXPRESSSION 2 THEN ...

  2. bzoj 5496: [2019省队联测]字符串问题【SAM+拓扑】

    有一个想法就是暴力建图,把每个A向有和他相连的B前缀的A,然后拓扑一下,这样的图是n^2的: 考虑优化建图,因为大部分数据结构都是处理后缀的,所以把串反过来,题目中要求的前缀B就变成了后缀B 建立SA ...

  3. NSA互联网公开情报收集指南:迷宫中的秘密·下

    猫宁!!! 参考链接: https://www.nsa.gov/news-features/declassified-documents/assets/files/Untangling-the-Web ...

  4. poj1273 Drainage Ditches 基础网络流

    #include <iostream> #include <queue> using namespace std; ][]; ]; //路径上每个节点的前驱节点 ]; int ...

  5. Json----Jackson 下载地址

    下载地址: http://repo1.maven.org/maven2/com/fasterxml/jackson/

  6. c++ const的使用

    const是用来声明一个常量的,当你不想让一个值被改变时就用const,const int max && int const max 是没有区别的,都可以.不涉及到指针const很好理 ...

  7. java 反向工具类

    1.ReflectUtil.java package com.example.scansell; import android.util.Log; import java.lang.reflect.C ...

  8. python_面向对象(6)

    第1章 递归函数 1.1 概述 1.2 练习 1.3 二分查找 第2章 面向对象•类 2.1 类的介绍 2.2 书写格式 2.3 类的属性 2.4 self介绍 2.5 类属性补充 2.6 调用查看静 ...

  9. 3. UITest笔记

    1.    XCUIApplication *app = [[XCUIApplication alloc] init]; App为查询的入口,当界面发生变化,查询数也会随之更新. 即使是先前存储的XC ...

  10. HEVC标准介绍+论文阅读笔记

    脱离视频编解码.投入计算机视觉一年,这个博客也歇业一年,最近偷些时间回顾一下编解码,毕竟花费了整个研一的时间(虽然这一年基本上在上课). 之前写过几篇H.264标准的几篇介绍文章,详见:http:// ...