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\),问最多能抽出多少个数, ...
随机推荐
- p1110 报表统计(FHQ-TREAP/TREAP)
平衡树的裸题,操作都相当简单 写了一个FHQ,但是奈何常数太大,实在过不去 最后写了一个Treap开O2水过 TREAP代码 #include <cstdio> #include < ...
- nginx 配置静态文件
location /temp/ { root F:/; autoindex on; } F:\temp 下的目录文件. 例子:http://localhost/temp/nginx-1.12.2/ht ...
- 良品铺子:“新零售”先锋的IT必经之路
良品铺子:“新零售”先锋的IT必经之路 云计算 大数据 CIO班 CIO 互联网+ 物联网 电子政务 2017-12-29 09:25:34 来源:互联网抢沙发 摘要:2017年被称为“新零售”元年 ...
- FI 业务
f-02 post f-03 clear[account]-> f-04 post with clear fb70/f-22 f-32 clear[account]->f-28 post ...
- android获取屏幕宽度和高度
1. WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); int wi ...
- 抗性基因数据库CARD介绍
随着抗生素药物的发现及使用,越来越多的耐药菌株由此产生.而耐药菌株的发展则会增加疾病治疗的难度和成本,因此耐药微生物的研究则显得尤为重要.目前,通过对耐药基因的鉴定挖掘能够一定程度上帮助我们揭开耐药机 ...
- 小程序学习一 .json 文件配置
微信小程序——配置 以下就是小编对小程序配置的资料进行的系统的整理,希望能对开发者有帮助. 我们使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置 ...
- 理解git的分支原理,更好地使用git
文章内容转载于git-scm. 部分内容涉嫌枯燥 一.git分支概念 几乎每一种版本控制系统都以某种形式支持分支.使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作.在很多版本控 ...
- 《Linux命令行与shell脚本编程大全》读书笔记
第一章:初识Linux 1.linux可划分为四个部分:内核.GNU工具.图形化桌面环境.应用程序 2.内核主要负责:系统内存管理.软件程序管理.硬件设备管理.文件系统管理 3.内核的系统内存管理,有 ...
- python shelve模块
#coding=utf- import shelve f = shelve.open("shelve_test") f['info'] = "alex" f[, ...