博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ.3522.[POI2014]Hotel(DP)
阅读量:4624 次
发布时间:2019-06-09

本文共 1269 字,大约阅读时间需要 4 分钟。

以为裸点分治,但数据范围怎么这么小?快打完了发现不对。。

n^2做的话其实是个水题。。

枚举每一个点为根,为了不重复计算,我们要求所求的三个点必须分别位于三棵子树上。
考虑当前前3棵子树深度为deep的点分别有a,b,c个,新增的子树深度为deep的点有d个,那么新加的答案为:
\[dab+dac+dbc=[ab+(a+b)c]*d\]
同理第5棵子树同一深度的点数为e,新加答案:
\[...=[ab+(a+b)c+(a+b+c)d]*e\]
那么第6棵子树新加的答案应为:
\[...=[ab+(a+b)c+(a+b+c)d+(a+b+c+d)e]*f\]
(以下sz表示每棵子树中处于某一深度的点数)

于是我们可以求每棵子树某一深度的点数,每次答案先加上当前 \(sz*[]里的式子\),再维护[]里的整个式子,即加上 \(sz*先前的子树和\),再更新子树的和(\(a+b+c...+=sz\))。

更好的方式是直接从组合理解,即答案加上当前子树乘上之前的子树中选两个的方案数,然后更新选两个的方案数,即 \(当前子树sz*之前子树选一个的方案数\),再更新子树中选一个的方案数,就是加上sz.

长链剖分:。

加强版需要长链剖分?好像用处不大先不管了。

//976kb 4808ms#include 
#include
#include
#include
#define gc() getchar()const int N=5005;int n,Enum,Maxd,H[N],nxt[N<<1],to[N<<1],c1[N],c2[N],sum[N];long long Ans;inline int read(){ int now=0;register char c=gc(); for(;!isdigit(c);c=gc()); for(;isdigit(c);now=now*10+c-'0',c=gc()); return now;}inline void AddEdge(int u,int v){ to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum; to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum; }void DFS(int x,int f,int d){ ++sum[d], Maxd=std::max(Maxd,d); for(int i=H[x]; i; i=nxt[i]) if(to[i]!=f) DFS(to[i],x,d+1);}int main(){ n=read(); for(int u,v,i=1; i

转载于:https://www.cnblogs.com/SovietPower/p/8663817.html

你可能感兴趣的文章
文献综述随笔(十七)
查看>>
JavaScript声音播放
查看>>
13个JavaScript图表(JS图表)图形绘制插件
查看>>
Bootstrap 辅助类
查看>>
各系统勒索补丁下载地址
查看>>
Multithreading For Performance
查看>>
解析新浪微博的登录过程
查看>>
最后N个元素 类问题的解题思想探究
查看>>
HTML5入门
查看>>
kali 软件源 包含virtualbox所需头文件
查看>>
获取电驴首页推荐信息和指定栏目信息
查看>>
《如何阅读一本书》读书笔记
查看>>
js 各种校验
查看>>
长链接生成短链接Java源码(调用百度接口)
查看>>
hdu5248 序列变换 二分
查看>>
学习CSS3BUTTON(二)
查看>>
[]和{},类的简写
查看>>
Android 中Parcelable的作用 (转载)
查看>>
编程每一天
查看>>
php选择语句
查看>>