【树论 倍增】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 /****************** ...
随机推荐
- 5 天 4000 star 的一个爆款开源项目
今天早上起来浏览 GitHub 的时候,在周热门趋势排行榜上看到了这么一个开源项目,仅仅 5 天时间,爬到了周排行榜的第一名的位置.而在每天的排行榜上,今天一早也高高位居排行榜的第二位. 这个开源项目 ...
- go系列(3)- go框架beego以及redis的使用
这篇讲讲如何在beego框架使用redis. golang中比较好用的第三方开源redisclient有: go-redis 源码地址:https://github.com/go-redis/redi ...
- djangoAdmin组件
定制后台页面功能 from django.contrib import admin from app import models # Register your models here. class ...
- 使用PHP操作SQL 完成简单的CURD操作
1.从数据库出发,先建立测试数据,这里使用的MYSQL,通过脚本模式创建测试数据. SET NAMES UTF8; DROP DATABASE IF EXISTS disk; CREATE DATAB ...
- aix 推荐使用重启
重启os AIX 主机 推荐 shutdown –Fr 在客户一次停机维护中,发现了这个问题. 环境是ORACLE 10G RAC for AIX6,使用了HACMP管理共享磁盘. 在停机维护时间段内 ...
- Xenu使用随记
经试验发现,如果配置了host进行网站检测时,Xenu和浏览器一样,都需要配置了host之后,重新打开Xenu程序(浏览器),host的配置才能生效.
- jQuery插件pagination.js源码解读
pagination的github地址:https://github.com/gbirke/jquery_pagination 公司用的是1.2的版本,所以我就读1.2的了. jQuery.fn.pa ...
- mac 终端查看端口命令
查看 端口所在线程 lsof -i:8080 mac-abeen:spider abeen$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF ...
- C 函数库 (libc,glibc,uClibc,newlib)
glibc glibc和libc都是Linux下的C函数库,libc是Linux下的ANSI C的函数库:glibc是Linux下的GUN C的函数库:GNU C是一种ANSI C的扩展实现.ANSI ...
- jmeter中通过命令方式生成结果文件
通过命令的方式将jmeter生成的jtl结果文件生成html文件,以便更直观的分析结果数据,以下命令可以放在1个bat文件中取执行. bat文件可以放到jmeter的根目录下. 步骤1: 通过命令方式 ...