【树论 倍增】51nod1709 复杂度分析
倍增与位运算有很多共性;这题做法有一点像「线段树上二分」和「线段树套二分」的关系。
Input
第一行一个数n表示点数(1<=n<=100,000)
接下来n-1行每行两个数x,y表示一条边(1<=x,y<=n)
Output
一个数表示答案
Input示例
4
1 2
1 3
2 4
Output示例
8
题目分析
题目已经良心地把要求的式子给出来了。
自上向下的方法一
位运算计数题自然而然考虑按位计算贡献,注意到要求的是bit即个数,也就是说高位和低位是同性的。而这题略有特殊的是在于可以与倍增相结合做一些有趣的事情。
由于边权为1,倍增预处理的到祖先节点的二的幂次,就是到祖先节点的距离的二进制拆分。
那么就可以先枚举logn数量的每一种2^i深度d,再枚举所有n个点。对于每一个枚举的点,统计与它相距2^{d-1}<dis≤2^d的祖先节点的贡献。
直观来说就是这张图。主要代码是这样的:
for (int d=; d<; d++)
{
memset(w, , sizeof w);
for (int ix=; ix<=n; ix++)
{
int i = chain[ix]; //树的dfs序,因为要自上向下做
w[i] = tot[f[i][d+]]-tot[f[i][d]];
if (dep[i] > <<(d+)) w[i] += w[fa[f[i][d+]]];
ans += w[i];
}
}
如果想要更加程式化的描述,见51Nod1709 复杂度分析这篇博客。
#include<bits/stdc++.h>
const int maxn = ; int n,w[maxn];
long long ans;
int chain[maxn],tot[maxn],chTot;
int f[maxn][],dep[maxn],fa[maxn];
int edgeTot,edges[maxn<<],nxt[maxn<<],head[maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs(int x, int fat)
{
f[x][] = x, f[x][] = fa[x] = fat, dep[x] = dep[fat]+;
tot[x] = , chain[++chTot] = x;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v!=fat){
dfs(v, x);
tot[x] += tot[v];
}
}
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<n; i++) addedge(read(), read());
dfs(, );
for (int j=; j<=; j++)
for (int i=; i<=n; i++)
f[i][j] = fa[f[f[i][j-]][j-]];
for (int d=; d<; d++)
{
memset(w, , sizeof w);
for (int ix=; ix<=n; ix++)
{
int i = chain[ix];
w[i] = tot[f[i][d+]]-tot[f[i][d]];
if (dep[i] > <<(d+)) w[i] += w[fa[f[i][d+]]];
ans += w[i];
}
}
printf("%lld\n",ans);
return ;
}
自上向下的方法二
在这里给出一种O(nlog)的做法。记录每个节点的fa和子树size。
枚举一个k,用s[i]表示节点i子树内和i距离小于 2^k 大于等于2^k−1的节点数,v[i]表示节点i子树内和i距离小于 2^k 大于等于 2^k−1 的节点和i距离的bit总数,now[i]表示i向上的第 2^k−1 个祖先。
每次倍增计算每个点子树内和它距离小于 2^k 大于等于 2^k−1 的点的距离对答案的贡献即可。@hzq84621 自http://www.51nod.com/question/index.html#!questionId=1546
【博客园抽风没法正常显示数学公式我也很难受啊】
END
【树论 倍增】51nod1709 复杂度分析的更多相关文章
- [51nod1709]复杂度分析
给出一棵n个点的树(以1号点为根),定义dep[i]为点i到根路径上点的个数.众所周知,树上最近公共祖先问题可以用倍增算法解决.现在我们需要算出这个算法精确的复杂度.我们定义计算点i和点j最近公共组先 ...
- 51nod1709复杂度分析
题解: 注意到,如果第j位有贡献,那么从i往上跳2^j,然后不能再跳超过2^j. 因此可以考虑倍增. 代码: #include<bits/stdc++.h> typedef long lo ...
- CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)
CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...
- 数据结构( Pyhon 语言描述 ) — — 第3章:搜索、排序和复杂度分析
评估算法的性能 评价标准 正确性 可读性和易维护性 运行时间性能 空间性能(内存) 度量算法的运行时间 示例 """ Print the running times fo ...
- bzoj5089 最大连续子段和 分块+复杂度分析+凸包
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5089 题解 本来打算迟一点再写这个题解的,还有一个小问题没有弄清楚. 不过先写一下存个档吧. ...
- [HNOI2016]树(可持久化线段树+树上倍增)
[HNOI2016]树(可持久化线段树+树上倍增) 题面 给出一棵n个点的模板树和大树,根为1,初始的时候大树和模板树相同.接下来操作m次,每次从模板树里取出一棵子树,把它作为新树里节点y的儿子.操作 ...
- 51nod 1709 复杂度分析
51nod 1709 复杂度分析 考虑定义 $ F(x) $ 为 \(x\) 为根的子树所有点与 $ x $ 的深度差(其实就是 $ x $ 到每个子树内点的距离)的 1 的个数和. 注意,$ F(x ...
- 分布式机器学习:同步并行SGD算法的实现与复杂度分析(PySpark)
1 分布式机器学习概述 大规模机器学习训练常面临计算量大.训练数据大(单机存不下).模型规模大的问题,对此分布式机器学习是一个很好的解决方案. 1)对于计算量大的问题,分布式多机并行运算可以基本解决. ...
- 相似度分析,循环读入文件(加入了HanLP,算法第四版的库)
相似度分析的,其中的分词可以采用HanLP即可: http://www.open-open.com/lib/view/open1421978002609.htm /****************** ...
随机推荐
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- Influxdb 时序数据库 windows 安装
Influxdb 是一款比较火爆的时序数据库,本文介绍如何在 windows 平台下安装. 1.场景: windows 平台的 influxdb 似乎只支持单机非windows 服务的安装方式 适用于 ...
- Longest Palindromic Substring笔记
这是一道在leetcode上看到的题目 一开始,我能想到的思路是蛮力法: 就遍历每个字符,然后对每个字符都尝试从1到n的长度,看有没有回文串,并记录以该字符起始的回文串的最大长度.这个思路其实没有上手 ...
- HDU 3359 高斯消元模板题,
http://acm.hdu.edu.cn/showproblem.php?pid=3359 题目的意思是,由矩阵A生成矩阵B的方法是: 以a[i][j]为中心的,哈曼顿距离不大于dis的数字的总和 ...
- WebForm随笔
一般处理程序中获取页面所传的值:int id = Convert.ToInt32(context.Request["id"]); 后台获取页面所传的值:int id = Conve ...
- js对象引用赋值后
a={f:1} b={} b.a=a console.log(b.a) a.b=2 console.log(b.a) a={f:1} b={} b.a=a console.log(b.a) a={b: ...
- 用python格式化小说txt
下载了<无人生还>的txt版.传到手机,发现阅读器识别得不够好. 原文格式如下: 第一章 一 沃格雷夫法官先生新近离任退休,现在正在头等车厢的吸烟室里,倚角而坐,一 边喷着雪茄烟,一边兴致 ...
- spring 上传附件
jsp: <form class='uk-form' action="savelead" method="post" enctype="mult ...
- PG extract 函数示例
pg 对时间的处理还是很灵活的, + - * / 都有支持 期间有个extract 函数还是很有用的,我们先来看看几个例子:[code] postgres=# select extract(epoc ...
- iphone开发设置默认字体
It seems to be possible in iOS 5 using the UIAppearance proxy. [[UILabel appearance] setFont:[UIFont ...