CF1009F Dominant Indices

思路:

1.可以理解为级儿子的个数
2.题目要求一个最小的使得最大,
3.存每个深度的节点个数,维护的最大值,维护对应的最小的深度
4.子树的答案就
复杂度:

用来标记的重儿子,然后统计的答案时绕过重儿子,统计完后取消重儿子的标记,因为除非要清空该重儿子,否则不会再访问到该重儿子。

每次都是在对以为根的子树信息进行统计,可以利用重儿子的数据。

MyCode:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7,maxm=2e6+7;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int head[maxn],Next[maxm],to[maxm],tot;
void add(int x,int y) {
    to[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
int size[maxn],son[maxn],dep[maxn];
int ans[maxn],pos,sum,cnt[maxn];
bool vis[maxn];
void dfs1(int x,int f) {
    size[x]=1;
    dep[x]=dep[f]+1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f) continue;
        dfs1(v,x);
        size[x]+=size[v];
        if(size[son[x]]<size[v]) son[x]=v;
    }
}
void calc(int x,int f) {
    cnt[dep[x]]+=1;
    if(cnt[dep[x]]==sum&&pos>dep[x]) pos=dep[x];
    else if(cnt[dep[x]]>sum) {
        sum=cnt[dep[x]];
        pos=dep[x];
    }
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f||vis[v]) continue;
        calc(v,x);
    }
}
void delet(int x,int f) {
    cnt[dep[x]]-=1;
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f) continue;
        delet(v,x);
    }
}
void dfs2(int x,int f,bool opt) {
    for(int i=head[x],v;i;i=Next[i]) {
        v=to[i];
        if(v==f||son[x]==v) continue;
        dfs2(v,x,false);
    }
    if(son[x]) {
        dfs2(son[x],x,true);
        vis[son[x]]=true;
    }
    calc(x,f);
    ans[x]=pos-dep[x];
    if(son[x]) vis[son[x]]=false;
    if(!opt) {
        delet(x,f);
        pos=sum=0;
    }
}
int main() {
    int n=read();
    for(int i=2,u,v;i<=n;++i) {
        u=read(),v=read();
        add(u,v);
        add(v,u);
    }
    dfs1(1,0);
    dfs2(1,0,false);
    for(int i=1;i<=n;++i) printf("%d ",ans[i]);
    return 0;
}
dsu on tree 文章被收录于专栏

启发式算法是什么呢? 启发式算法是基于人类的经验和直观感觉,对一些算法的优化。 适用于: 1.无修改操作,询问允许离线 2.对子树信息进行统计(链上的信息在某些条件下也可以统计) 也可以用莫队、点分治 但dsu on tree可以把它们吊起来打! dsu on tree运用树剖中的轻重链剖分,将轻边子树信息累加到重链上进行统计,拥有 O(nlogn) 的优秀复杂度,常数还贼小

全部评论

相关推荐

02-14 12:40
门头沟学院 Java
程序员花海:1.面试要求必须Java笔试不一定 2.难度对等秋招 远超于日常实习是因为同一批次且转正很多 竞争压力大 3.第一个加点指标,上线了就把接口性能加上去 使用本地缓存这个不算亮点 只是技术选型,要把为什么采用这个和背后的思考写出来而不是单纯堆叠技术没意义 4.八股要一直看 很容易忘记 5.拼团交易这个老问题 堆积技术 另外建议你把奖项合并到教育背景 没必要拆出来放最后
我的简历长这样
点赞 评论 收藏
分享
02-26 09:15
已编辑
蚌埠学院 golang
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务