Educational Codeforces Round 2 E - Lomsat gelral
题意:每个节点有个值,求每个节点子树众数和
题解:可线段树合并,维护每个数出现次数和最大出现次数,以及最大出现次数的数的和
//#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的更多相关文章
- 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 ...
- Educational Codeforces Round 2 E. Lomsat gelral(dsu)
题目链接 题意:给你一棵以1为根n个点的树,问你以i为根的子树的众数和是多少 思路:dsu是一种优化暴力的手段 首先进行轻重链剖分 然后只记录重链的信息 轻链的信息就直接暴力查找 经过证明这样复杂度可 ...
- [Educational Codeforces Round 16]E. Generate a String
[Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...
- [Educational Codeforces Round 16]D. Two Arithmetic Progressions
[Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...
- [Educational Codeforces Round 16]C. Magic Odd Square
[Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...
- [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 ...
- [Educational Codeforces Round 16]A. King Moves
[Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...
- Educational Codeforces Round 6 C. Pearls in a Row
Educational Codeforces Round 6 C. Pearls in a Row 题意:一个3e5范围的序列:要你分成最多数量的子序列,其中子序列必须是只有两个数相同, 其余的数只能 ...
- Educational Codeforces Round 9
Educational Codeforces Round 9 Longest Subsequence 题目描述:给出一个序列,从中抽出若干个数,使它们的公倍数小于等于\(m\),问最多能抽出多少个数, ...
随机推荐
- s2-045漏洞批量检测工具
今天晚上看老铁们在群里就这个st2-045漏洞讨论得火热,个人不太喜欢日站,本来想直接写个批量挂马的东西,但是想想还是算了,如果你有兴趣,改改也很容易,反正不关我的事 测试图 2017-3-8更新 增 ...
- 【特性】Redis4.0新特性
模块系统 Redis 4.0 发生的最大变化就是加入了模块系统, 这个系统可以让用户通过自己编写的代码来扩展和实现 Redis 本身并不具备的功能, 具体使用方法可以参考 antirez 的博文< ...
- Luncene学习 第一天 《入门程序》
整个luncene 流程 下面贴出代码 package com.zuoyan.lucene.demo; import java.io.File; import org.apache.commons.i ...
- 剥开比原看代码10:比原是如何通过/create-key接口创建密钥的
作者:freewind 比原项目仓库: Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchai ...
- Transaction
SqlTransaction——事务详解 事务是将一系列操作作为一个单元执行,要么成功,要么失败,回滚到最初状态.在事务处理术语中,事务要么提交,要么中止.若要提交事务,所有参与者都必须保证对数据的任 ...
- Linux学习之用户与root
因为想要建立建立一个目录,但是发现权限不够,因为没用root登陆,所以学习了一下普通用户与root之间如何切换以及如何创建用户的一些知识. 1.pwd命令可以查看当前用户 $这个符号代表的就是普通用户 ...
- Linux 命令之mv
mv命令也是Linux中很常见命令 作用:可以用来移动文件或者将文件改名 命令格式: mv [选项] 源文件或目录 目标文件或目录 命令参数: -b :若需覆盖文件,则覆盖前先行备份. -f :for ...
- 【Java】【图形】
/* 栗子 了解swing */import javax.swing.*;public class test_swing extends JFrame { //继承JFrame顶层容器类(可以添加其他 ...
- React入门实例:组件化+react-redux实现网上商城(1)
项目运行 1.git clone https://github.com/soybeanxiaobi/React_demo_onlineShop 2.cd React_demo_onlineShop(文 ...
- Program type already present:okio.AsyncTimeout$Watchdog Message{kind=ERROR, text=Program type :okio
在app中的build.gradle中加入如下代码, configurations { all*.exclude group: 'com.google.code.gson' all*.exclude ...