题意:有一棵树,对于每个点求子树中离他深度最多的深度是多少,
题解:线段树合并快如闪电,每个节点开一个权值线段树,递归时合并即可,然后维护区间最多的是哪个权值,到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\n",l,r);
if(l==r)
{
if(!x||!y)
{
ma[x+y]=ma[x]+ma[y];
// printf("%d %d %d %d %d %d\n",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\n",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---\n",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\n",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\n",ans[i]);
return 0;
}
/********************
4
1 2
1 3
1 4
********************/
原文地址:https://www.cnblogs.com/acjiumeng/p/9339091.html
时间: 2024-11-06 07:35:47