题意:每个节点有个值,求每个节点子树众数和

题解:可线段树合并,维护每个数出现次数和最大出现次数,以及最大出现次数的数的和

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#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")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
//#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#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 Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;} using namespace std; const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=100000+10,maxn=50000+10,inf=0x3f3f3f3f; vi v[N];
int root[N*22];
int ls[N*22],rs[N*22],tot,n;
ll ans[N],sum[N*22],num[N*22],ma[N*22];
void pushup(int o)
{
ma[o]=max(ma[ls[o]],ma[rs[o]]);
if(ma[ls[o]]==ma[rs[o]])sum[o]=sum[ls[o]]+sum[rs[o]];
else if(ma[ls[o]]>ma[rs[o]])sum[o]=sum[ls[o]];
else sum[o]=sum[rs[o]];
}
inline int Merge(int x,int y,int l,int r)
{
if(l==r)
{
if(!x||!y)
{
ma[x+y]=num[x+y]=num[x]+num[y];
sum[x+y]=l;
return x+y;
}
else
{
ma[x]=num[x]=num[x]+num[y];
sum[x]=l;
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 build(int &o,int pos,int l,int r)
{
if(!o)o=++tot;
if(l==r)
{
ma[o]=num[o]=1;
sum[o]=l;
return ;
}
int m=(l+r)>>1;
if(pos<=m)build(ls[o],pos,l,m);
else build(rs[o],pos,m+1,r);
pushup(o);
}
void debug(int o,int l,int r)
{
printf("%d+++%d %d %d %d %d\n",o,sum[o],num[o],ma[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);
}
void dfs(int u,int f)
{
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(x!=f)dfs(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);
}
ans[u]=sum[root[u]];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
build(root[i],x,1,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);
for(int i=1;i<=n;i++)printf("%lld ",ans[i]);puts("");
return 0;
}
/********************
4
1 2 2 4
1 2
2 3
2 4
********************/

也可dsu on tree,先轻重链剖分,每次递归时保留重儿子的子树信息,统计答案时,先递归轻儿子统计子树信息,然后统计完后删除信息,维护每个次数的和

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#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")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
//#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#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 Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;} using namespace std; const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=100000+10,maxn=50000+10,inf=0x3f3f3f3f; vi v[N];
int c[N],sz[N],l[N],r[N],id[N],cnt,n;
ll num[N],sum[N],maxx,ans[N];
void dfs(int u,int f)
{
sz[u]=1;
l[u]=++cnt;id[cnt]=u;
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(x!=f)
{
dfs(x,u);
sz[u]+=sz[x];
}
}
r[u]=cnt;
}
void solve(int u,int f,bool keep)
{
int ma=-1,son=-1;
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(x!=f&&ma<sz[x])ma=sz[x],son=x;
}
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(x!=f&&x!=son)solve(x,u,0);
}
if(son!=-1)solve(son,u,1);
for(int i=0;i<v[u].size();i++)
{
int x=v[u][i];
if(x!=f&&x!=son)for(int j=l[x];j<=r[x];j++)
{
sum[num[c[id[j]]]]-=c[id[j]];
num[c[id[j]]]++;
sum[num[c[id[j]]]]+=c[id[j]];
maxx=max(maxx,num[c[id[j]]]);
}
}
sum[num[c[u]]]-=c[u];
num[c[u]]++;
sum[num[c[u]]]+=c[u];
maxx=max(maxx,num[c[u]]);
ans[u]=sum[maxx];
if(!keep)for(int i=l[u];i<=r[u];i++)
{
sum[num[c[id[i]]]]-=c[id[i]];
num[c[id[i]]]--;
sum[num[c[id[i]]]]+=c[id[i]];
if(sum[maxx]==0)maxx--;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
sum[0]+=i;
}
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);
solve(1,-1,0);
for(int i=1;i<=n;i++)printf("%lld ",ans[i]);puts("");
return 0;
}
/********************
3
1 2 3
1 2
1 3
********************/

Educational Codeforces Round 2 E - Lomsat gelral的更多相关文章

  1. Educational Codeforces Round 2 E. Lomsat gelral 启发式合并map

    E. Lomsat gelral Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/prob ...

  2. Educational Codeforces Round 2 E. Lomsat gelral(dsu)

    题目链接 题意:给你一棵以1为根n个点的树,问你以i为根的子树的众数和是多少 思路:dsu是一种优化暴力的手段 首先进行轻重链剖分 然后只记录重链的信息 轻链的信息就直接暴力查找 经过证明这样复杂度可 ...

  3. [Educational Codeforces Round 16]E. Generate a String

    [Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...

  4. [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...

  5. [Educational Codeforces Round 16]C. Magic Odd Square

    [Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...

  6. [Educational Codeforces Round 16]B. Optimal Point on a Line

    [Educational Codeforces Round 16]B. Optimal Point on a Line 试题描述 You are given n points on a line wi ...

  7. [Educational Codeforces Round 16]A. King Moves

    [Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...

  8. Educational Codeforces Round 6 C. Pearls in a Row

    Educational Codeforces Round 6 C. Pearls in a Row 题意:一个3e5范围的序列:要你分成最多数量的子序列,其中子序列必须是只有两个数相同, 其余的数只能 ...

  9. Educational Codeforces Round 9

    Educational Codeforces Round 9 Longest Subsequence 题目描述:给出一个序列,从中抽出若干个数,使它们的公倍数小于等于\(m\),问最多能抽出多少个数, ...

随机推荐

  1. C# 里调用vb的inputbox弹出窗

    https://blog.csdn.net/hutao1101175783/article/details/16800871 先对项目添加对Microsoft.VisualBasic的引用 Inter ...

  2. 论文笔记:Show, Attend and Tell: Neural Image Caption Generation with Visual Attention

    Show, Attend and Tell: Neural Image Caption Generation with Visual Attention 2018-08-10 10:15:06 Pap ...

  3. Kubernetes命令

    kubectl applykubectl getkubectl set image deployment/xxx -n ns  echoservice=xxxkubectl deletekubectl ...

  4. 【转载】谈谈自己对REST、SOA、SOAP、RPC、ICE、ESB、BPM知识汇总及理解

    转载自:https://blog.csdn.net/tantexian/article/details/48196453 SOA: 维基百科解释:SOA:面向服务的软件架构(Service Orien ...

  5. ngui项目花屏问题

    项目用的ngui 最近在金立手机上遇到一个问题就是  启动的时候会花一下屏幕 一闪而过  由于ngui默认camera使用的是clear depth  所以按照网上的办法修改 color 跟skybo ...

  6. P4574 [CQOI2013]二进制A+B

    传送门 思路: 本题可用数位DP来做,设 f [ i ][ a ][ b ][ c ][ j ] 表示当前枚举到(二进制下的)第i位,a' b' c'各用a,b,c了几个1,j表示最后一位是否有进位. ...

  7. rm

    rm [选项]... 目录... 删除指定的<文件>(即解除链接). -d      --directory    删除可能仍有数据的目录 (只限超级用户)-f      --force  ...

  8. vue组件定义全局方法

    1.在vue实例的data中定义一个对象 2.可以在其他组件定义方法 3.触发方法

  9. &&并且, ||或 , 的用法 ,区别

    &&与运算必须同时都为true才是true,如果左边为false结果肯定为false: ||或运算,只要左边为true结果一定为true,两边都为false结果才是false. 只有当 ...

  10. 远程Service的显示 / 隐式启动

    在进程间通信时,常会设计开启远程 Service 的情况.开启远程 Service 的方式有两种,一种时显示开启,一种是隐式开启.下面分别来看: 一.隐式开启 服务端:Service 所在 Andro ...