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的?

代码

  1. #include<bits/stdc++.h>
  2. clock_t t=clock();
  3. namespace my_std{
  4. using namespace std;
  5. #define pil pair<int,ll>
  6. #define fir first
  7. #define sec second
  8. #define MP make_pair
  9. #define rep(i,x,y) for (int i=(x);i<=(y);i++)
  10. #define drep(i,x,y) for (int i=(x);i>=(y);i--)
  11. #define go(x) for (int i=head[x];i;i=edge[i].nxt)
  12. #define templ template<typename T>
  13. #define sz 505050
  14. typedef long long ll;
  15. typedef double db;
  16. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  17. templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
  18. templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
  19. templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
  20. templ inline void read(T& t)
  21. {
  22. t=0;char f=0,ch=getchar();double d=0.1;
  23. while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
  24. while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
  25. if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
  26. t=(f?-t:t);
  27. }
  28. template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
  29. char __sr[1<<21],__z[20];int __C=-1,__zz=0;
  30. inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
  31. inline void print(register int x)
  32. {
  33. if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
  34. while(__z[++__zz]=x%10+48,x/=10);
  35. while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
  36. }
  37. void file()
  38. {
  39. #ifdef NTFOrz
  40. freopen("a.in","r",stdin);
  41. #endif
  42. }
  43. inline void chktime()
  44. {
  45. #ifndef ONLINE_JUDGE
  46. cout<<(clock()-t)/1000.0<<'\n';
  47. #endif
  48. }
  49. #ifdef mod
  50. 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;}
  51. ll inv(ll x){return ksm(x,mod-2);}
  52. #else
  53. ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
  54. #endif
  55. // 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;}
  56. }
  57. using namespace my_std;
  58. int n;
  59. struct hh{int t,nxt;}edge[sz<<1];
  60. int head[sz],ecnt;
  61. void make_edge(int f,int t)
  62. {
  63. edge[++ecnt]=(hh){t,head[f]};
  64. head[f]=ecnt;
  65. edge[++ecnt]=(hh){f,head[t]};
  66. head[t]=ecnt;
  67. }
  68. ll dp[sz];
  69. int size[sz];
  70. ll ans=1e18;
  71. #define v edge[i].t
  72. #define Sqr(x) (1ll*(x)*(x))
  73. inline db K(pil a,pil b){return 1.0*(b.sec-a.sec)/(b.fir-a.fir);}
  74. void dfs(int x,int fa)
  75. {
  76. vector<pil>V;size[x]=1;
  77. go(x) if (v!=fa)
  78. {
  79. dfs(v,x);
  80. V.push_back(MP(size[v],dp[v]-2ll*n*size[v]+Sqr(size[v])));
  81. size[x]+=size[v];
  82. }
  83. dp[x]=Sqr(size[x]);
  84. go(x) if (v!=fa) chkmin(dp[x],dp[v]+Sqr(size[x]-size[v]));
  85. if (!V.size()) return;
  86. sort(V.begin(),V.end());
  87. vector<pil>con;con.push_back(V[0]);int top=0;
  88. rep(i,1,(int)V.size()-1)
  89. {
  90. while (top&&K(con[top],con[top-1])>-2*V[i].fir) --top,con.pop_back();
  91. chkmin(ans,con[top].sec+V[i].sec+2ll*con[top].fir*V[i].fir+Sqr(n));
  92. if (V[i].fir==V[i-1].fir) continue;
  93. while (top&&K(con[top],con[top-1])>=K(con[top-1],V[i])) --top,con.pop_back();
  94. con.push_back(V[i]);++top;
  95. }
  96. }
  97. int main()
  98. {
  99. file();
  100. int x,y;
  101. read(n);
  102. rep(i,1,n-1) read(x,y),make_edge(x,y);
  103. dfs(1,0);chkmin(ans,dp[1]);
  104. ll Ans=(Sqr(n)-ans)/2+1ll*n*(n-1)/2;
  105. cout<<Ans;
  106. return 0;
  107. }

其他解法

参见 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. Linear Regression_最小二乘(LMS)

    %% Machine Learining----Linear Regression close all clear %%data load Year = linspace(,,); Price = [ ...

  2. Linux中的gdb调试方法总结

  3. Linux 问题 卸载setup.py方式安装的python包

    python ./setup.py install --record install.txt  cat install.txt | xargs rm -rf

  4. bzoj 3697: 采药人的路径【点分治】

    点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路 ...

  5. Luogu P1262 间谍网络 【强连通分量/缩点】By cellur925

    题目传送门 真是一道好题呀~~~~qwq 知道这题是tarjan,但是想了很久怎么用上强连通分量.因为样例们...它显然并不是一个强联通分量! (被样例迷惑的最好例子) 然后...就没有然后了...感 ...

  6. bzoj2301 [HAOI2011]Problem b【莫比乌斯反演 分块】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301 很好的一道题.首先把每个询问转化为4个子询问,最后的结果就是这四个子询问的记过加加减减 ...

  7. Helga Hufflepuff's Cup CodeForces - 855C

    Helga Hufflepuff's Cup CodeForces - 855C 题意:给一棵n个节点的树,要给每一个节点一个附加值,附加值可以为1-m中的一个整数.要求只能有最多x个节点有附加值k. ...

  8. 并查集 HDOJ 5441 Travel

    题目传送门 题意:给一张无向图,问存在多少(a, b)表示a点到b点经过的边值小于等于x ((a,b) 和 (b, a)属于不同的方案) 分析:首先将边权值和查询x值升序排序,从前往后扫描边,累加从u ...

  9. 491 Increasing Subsequences 递增子序列

    给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2.示例:输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, ...

  10. vue 模拟后台数据(加载本地json文件)调试

    首先创建一个本地json文件,放在项目中如下 { "runRedLight":{ "CurrentPage": 1, "TotalPages" ...