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

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

//#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. 论文笔记:ReNet: A Recurrent Neural Network Based Alternative to Convolutional Networks

    ReNet: A Recurrent Neural Network Based Alternative to Convolutional Networks2018-03-05  11:13:05   ...

  2. 4-Four-Seeing hands

      ①Several cases have been reported in Russia recently of people who can read and detect colours wit ...

  3. Unity3D学习笔记(二十八):Editor

    Editor: 对编辑器进行一些拓展开发 关于继承Mono类的扩展开发   特性: [特性]:声明性的标签(类,方法,结构体,变量) 特性只对字段声明有效,后面必须接字段:多个特性,可以修饰一个字段 ...

  4. 【C#】C#学习笔记_1

    C#的程序入口为某一个类里面的static void Main(string[] args){}方法,如果一个工程有多个Main方法,那么需要在工程配置中选择一个作为程序入口. C#的输入.输出操作在 ...

  5. mySql 数据库设计原则

    mysql数据库设计原则: 必须使用InnoDB存储引擎 解读:支持事务.行级锁.并发性能更好.CPU及内存缓存页优化使得资源利用率更高 禁止使用存储过程.视图.触发器.Event 解读:高并发大数据 ...

  6. 【C#】委托的发展

    "用事件去处理程序, 进而解决问题" ---- 委托的目的 委托早在C#2的时候就已经初具模型, 但是并不是特别灵活, 制止C#3才在代码中被广泛使用. C#4中泛型委托, C#5 ...

  7. spring-tool-suite使用教程,并创建spring配置文件

    本文为博主原创,未经允许不得转载: 在应用springMVC框架的时候,每次创建spring的xml配置文件时,需要很多步骤,非常麻烦. 所以spring提供了spring-tool-suite插件, ...

  8. BZOJ 1143: [CTSC2008]祭祀river(二分图最大点独立集)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1143 题意: 思路: 二分图最大点独立集,首先用floyd判断一下可达情况. #include< ...

  9. Jmeter干货 不常用却极其有用的几个地方

    1. Jmeter测试计划下Run Thread Groups consecutively 表示序列化执行测试计划下所有线程组中的各个请求 如下图配置,新建的测试计划中,不默认勾选此项, 而享用Jme ...

  10. Python中cPickle

    cPickle模块: 在python中,一般可以使用pickle类来进行python对象序列化,而cPickle提供了一个更快速简单的接口,如python文档所说:“cPickle - A faste ...