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$ 的答案. 对于要消除暴力消除即 ...
随机推荐
- Educational Codeforces Round 71 (Rated for Div. 2) Solution
A. There Are Two Types Of Burgers 题意: 给一些面包,鸡肉,牛肉,你可以做成鸡肉汉堡或者牛肉汉堡并卖掉 一个鸡肉汉堡需要两个面包和一个鸡肉,牛肉汉堡需要两个面包和一个 ...
- hdu 1269 入手强连通
思路待整理 #include<cstdio> #include<iostream> #include<cstring> #include<vector> ...
- Oracle 以及 PLSQL安装
今天重装系统遇到oracle 安装的问题咯 ,oracle安装过程中很多疑难杂症咯 1如果之前装过,记得去删除注册表的Oracle 相关的文件 ,请百度有很多教程咯 2这个必须要勾选的!因为的是11g ...
- SQLServer从渣仔到小白
一.将查询结果插入到另一张表 1. 查询结果插入新表 select * into tableA from tableB where … 2. 查询结果插入已经存在的表 insert into tabl ...
- 爬虫遇到IP访问频率限制的解决方案
背景: 大多数情况下,我们遇到的是访问频率限制.如果你访问太快了,网站就会认为你不是一个人.这种情况下需要设定好频率的阈值,否则有可能误伤.如果大家考过托福,或者在12306上面买过火车票,你应该会有 ...
- DX使用随记--TabControl
1. 关闭TabControl选项卡: Private Sub TabControl_Main_CloseButtonClick(sender As Object, e As EventArgs) H ...
- SpringBoot之Redis访问(spring-boot-starter-data-redis)
依赖注入: <!--dependency for redis--> <!-- https://mvnrepository.com/artifact/org.springframewo ...
- 运行tomcat7w.exe提示指定的服务未安装 解决办法
一.问题重现点击bin下tomcat7w.exe出现如下提示:提示指定的服务未安装 二.原因分析tomcat7.exe和tomcat7w.exe要起作用必须先为这两个文件安装服务.其中tomcat7. ...
- 随机模块 random 函数的调用
随机模块 random 作用: 用于模拟或生成随机输出的模块. 用法示意: import random as R 函数名 描述 R.random() 返回一个[0, 1) 之间的随机实数 R.unif ...
- mysql tinyint(1) 在java中被转化为boolean
数据库表字段类型为:tinyint 长度为1 在java中对应的类型是boolean 查询时直接在页面展示成true或false 如果是2,3,4 这样的也是默认成true,非常不友好. 解决方案: ...