Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并

Posted acjiumeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并相关的知识,希望对你有一定的参考价值。

题意:有一棵树,对于每个点求子树中离他深度最多的深度是多少,
题解:线段树合并快如闪电,每个节点开一个权值线段树,递归时合并即可,然后维护区间最多的是哪个权值,到x的深度就是到根的深度减去x到根的深度复杂度O(nlogn)

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
//#define vi vector<int>
#define mod 998244353
#define ld long double
#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double eps=1e-6;
const int N=1000000+10,maxn=50000+10,inf=0x3f3f3f3f;

vector<int> v[N];
int deep[N];
void dfs(int u,int f,int dep)
{
    deep[u]=dep;
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        if(x!=f)dfs(x,u,dep+1);
    }
}
int root[N],ma[N*22],ind[N*22];
int ls[N*22],rs[N*22],tot;
inline void pushup(int o)
{
    if(ma[ls[o]]>=ma[rs[o]])ma[o]=ma[ls[o]],ind[o]=ind[ls[o]];
    else ma[o]=ma[rs[o]],ind[o]=ind[rs[o]];
}
inline int Merge(int x,int y,int l,int r)
{
//    printf("%d----------------------------%d
",l,r);
    if(l==r)
    {
        if(!x||!y)
        {
            ma[x+y]=ma[x]+ma[y];
//            printf("%d %d %d %d %d %d
",x,ma[x],y,ma[y],l,r);
            return x+y;
        }
        else
        {
            ma[x]=ma[x]+ma[y];
//            printf("%d %d %d %d %d %d
",x,ma[x],y,ma[y],l,r);
            return x;
        }
    }
    if(!x||!y)return x+y;
    int m=(l+r)>>1;
    ls[x]=Merge(ls[x],ls[y],l,m);
    rs[x]=Merge(rs[x],rs[y],m+1,r);
    pushup(x);
    return x;
}
void update(int &o,int pos,int l,int r)
{
    if(!o)o=++tot;
//    printf("%d %d %d %d---
",l,r,pos,o);
    if(l==r){ma[o]++;ind[o]=l;return ;}
    int m=(l+r)>>1;
    if(pos<=m)update(ls[o],pos,l,m);
    else update(rs[o],pos,m+1,r);
    pushup(o);
}
void debug(int o,int l,int r)
{
//    printf("%d+++%d %d %d %d
",o,ma[o],ind[o],l,r);
    if(l==r)return ;
    int m=(l+r)>>1;
    if(ls[o])debug(ls[o],l,m);
    if(rs[o])debug(rs[o],m+1,r);
}
int ans[N],n;
void solve(int u,int f)
{
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        if(x!=f)solve(x,u);
    }
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        if(x!=f)
        {
            root[u]=Merge(root[u],root[x],1,n);
//            puts("****************8");
//            debug(root[id[u]],1,n);
//            puts("!!!!!");
        }
    }
//    debug(root[id[u]],1,n);
//    puts("------------");
    ans[u]=ind[root[u]]-deep[u];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        v[a].pb(b),v[b].pb(a);
    }
    dfs(1,-1,1);
    for(int i=1;i<=n;i++)
        update(root[i],deep[i],1,n);
    solve(1,-1);
    for(int i=1;i<=n;i++)printf("%d
",ans[i]);
    return 0;
}
/********************
4
1 2
1 3
1 4
********************/

以上是关于Educational Codeforces Round 47 (Rated for Div. 2)F. Dominant Indices 线段树合并的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27