Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)
F. Dominant Indices
题意:
给一颗无向树,根为1。对于每个节点,求其子树中,哪个距离下的节点数量最多。数量相同时,取较小的那个距离。
题目:
这类题一般的做法是树上的启发式合并,复杂度是O(nlogn)。但由于这题所求的信息与深度有关,因此可以使用长链剖分的技巧,复杂度可以是O(n)。
长链剖分可以维护以深度为下标的信息。先预处理,以深度为依据,标记长儿子。维护答案时,对于每个节点,O(1)继承其长儿子的信息。然后暴力合并其他儿子。则时间复杂度是所有长链的长度之和,即O(n)。对于空间而言,可以通过维护一根指针来合理分配空间,使得所用空间也是线性的。
代码:
#include<bits/stdc++.h>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<"\n"
#define sz(x) int(x.size())
#define All(x) x.begin(),x.end()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef priority_queue<int> BQ;
typedef priority_queue<int,vector<int>,greater<int> > SQ;
const int maxn=1e6+10,mod=1e9+7,INF=0x3f3f3f3f;
vector<int> G[maxn];
int deep[maxn],maxd[maxn],son[maxn],ans[maxn];
void dfs1(int fa,int u)
{
deep[u]=maxd[u]=deep[fa]+1;
for (auto& v:G[u])
{
if (v==fa)
continue;
dfs1(u,v);
if (maxd[v]>maxd[u])
maxd[u]=maxd[v],son[u]=v;
}
}
int tmp[maxn],*p=tmp,*sum[maxn];
void dfs2(int fa,int u)
{
sum[u][0]=1;
if (son[u])
{
sum[son[u]]=sum[u]+1;
dfs2(u,son[u]);
ans[u]=ans[son[u]]+1;
}
for (auto& v:G[u])
{
if (v==fa||v==son[u])
continue;
sum[v]=p;
p+=maxd[v]-deep[v]+1;
dfs2(u,v);
for (int i=0;i<=maxd[v]-deep[v];++i)
{
sum[u][i+1]+=sum[v][i];
if ((sum[u][i+1]>sum[u][ans[u]])||(sum[u][i+1]==sum[u][ans[u]]&&i+1<ans[u]))
ans[u]=i+1;
}
}
if (sum[u][ans[u]]==1)
ans[u]=0;
}
int main()
{
int n;
cin>>n;
for (int i=1;i<n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].pb(v);
G[v].pb(u);
}
dfs1(0,1);
sum[1]=p;
p+=maxd[1];
dfs2(0,1);
for (int i=1;i<=n;++i)
printf("%d\n",ans[i]);
return 0;
}
Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)的更多相关文章
- CF 1009 F Dominant Indices —— 长链剖分+指针
题目:http://codeforces.com/contest/1009/problem/F 也可以用 dsu on tree 的做法,全局记录一个 dep,然后放进堆里,因为字典序要最小,所以再记 ...
- 【CodeChef EDGEST】Edges in Spanning Trees(树链剖分+树上启发式合并)
点此看题面 大致题意: 给你两棵\(n\)个点的树,对于第一棵树中的每条边\(e_1\),求存在多少条第二棵树中的边\(e_2\),使得第一棵树删掉\(e_1\)加上\(e_2\).第二棵树删掉\(e ...
- CF1009F Dominant Indices 长链剖分
题目传送门 https://codeforces.com/contest/1009/problem/F 题解 长链剖分的板子吧. 令 \(dp[x][i]\) 表示 \(x\) 的子树中的深度为 \( ...
- CF1009F Dominant Indices——长链剖分优化DP
原题链接 \(EDU\)出一道长链剖分优化\(dp\)裸题? 简化版题意 问你每个点的子树中与它距离为多少的点的数量最多,如果有多解,最小化距离 思路 方法1. 用\(dsu\ on\ tree\)做 ...
- Codeforces 1009 F - Dominant Indices
F - Dominant Indices 思路:树上启发式合并 先跑轻子树,然后清除轻子树的信息 最后跑重子树,不清除信息 然后再跑一遍轻子树,重新加回轻子树的信息 由于一个节点到根节点最多有logn ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- 【CF1009F】 Dominant Indices (长链剖分+DP)
题目链接 \(O(n^2)\)的\(DP\)很容易想,\(f[u][i]\)表示在\(u\)的子树中距离\(u\)为\(i\)的点的个数,则\(f[u][i]=\sum f[v][i-1]\) 长链剖 ...
- 【CF1009F】Dominant Indices(长链剖分优化DP)
点此看题面 大致题意: 设\(d(x,y)\)表示\(x\)子树内到\(x\)距离为\(y\)的点的个数,对于每个\(x\),求满足\(d(x,y)\)最大的最小的\(y\). 暴力\(DP\) 首先 ...
- dsu on tree 与长链剖分
dsu on tree 对于树进行轻重链剖分,对于节点 $x$ ,递归所有轻儿子后消除其影响,递归重儿子,不消除其影响. 然后对于所有轻儿子的子树暴力,从而得到 $x$ 的答案. 对于要消除暴力消除即 ...
随机推荐
- Python 语言简介与入门
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- Invalid default value for 'time'
原因:安装的MySQL5.7版本之后,date, datetime类型设置默认值"0000-00-00",出现异常:Invalid default value for 'time' ...
- hdu 2066 Dijstra 堆优化
嗯 有广搜的意思 #include<cstdio> #include<iostream> #include<queue> #include<vector> ...
- Java生成随机数列表
生成随机数列表 1.Java8以前 (1)Math.random private List<UserEntity> random1() { ArrayList<UserEntity& ...
- 给postmessage加上callback方法
postmessage双向通信中,是不能使用回调函数的. window.postmessage({msg:'hello',callback:function(e){ do something with ...
- layer,备受青睐的web弹层组件
//http://layer.layui.com/ 特别说明:事件需自己绑定,以下只展现调用代码. //初体验 layer.alert('内容') //第三方扩展皮肤 layer.alert('内容' ...
- Sharepoint2010设置自定义母版页
前言 这个文档是为Microsoft Sharepoint2010 上海文档库公司站点设计的母版页,其版本为1.0,为相关的源文件编写的使用说明书. 使用SharePoint Designer 201 ...
- 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?
1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...
- Centos7.7安装swoole
系统版本:centos 7.7(查看系统版本:cat /etc/redhat-release) 执行命令安装swoole: yum update -y && yum remove ph ...
- Delphi 类类型