标签:Node val int text sum fx gelral CF600E void
两种算法:
- 线段树合并
- \(\text{DSU on tree}\)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
using LL = long long;
namespace SegmentTree_Combination {
namespace Sg {
#define mid (l + r >> 1)
struct Node {
Node *l, *r;
LL val, sum;
}*nil;
inline void init(Node *&p) {
p->l = p->r = nil;
p->val = p->sum = 0;
}
inline void pushup(Node *p) {
if(p->l->val > p->r->val) p->val = p->l->val, p->sum = p->l->sum;
else if(p->l->val < p->r->val) p->val = p->r->val, p->sum = p->r->sum;
else p->val = p->l->val, p->sum = p->l->sum + p->r->sum;
}
void update(Node *&p, int l, int r, int x, int v) {
if(p == nil) init(p = new Node());
if(l == r) return p->sum = l, p->val += v, void();
x <= mid ? update(p->l, l, mid, x, v) : update(p->r, mid + 1, r, x, v);
pushup(p);
}
Node *Mg(Node *p, Node *q, int l, int r) {
if(p == nil) return q; if(q == nil) return p;
if(l == r) { p->val += q->val, p->sum = l; return p; }
p->l = Mg(p->l, q->l, l, mid), p->r = Mg(p->r, q->r, mid + 1, r);
pushup(p); return p;
}
}
int n, col[N];
LL ret[N];
vector <int> Link[N];
struct Sgtree {
Sg::Node *rt;
inline void update(int x, int v) { Sg::update(rt, 1, n, x, v); }
inline void Merge(Sgtree *that) { rt = Sg::Mg(this->rt, that->rt, 1, n); }
inline LL query() { return rt->sum; }
}s[N];
void dfs(int u, int F) {
s[u].update(col[u], 1);
for(auto v : Link[u]) {
if(v == F) continue;
dfs(v, u);
s[u].Merge(&s[v]);
}
ret[u] = s[u].query();
}
signed main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("Ans.txt", "w", stdout);
#endif
Sg::init(Sg::nil = new Sg::Node());
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", col + i);
for(int i = 1; i < n; ++i) {
register int x, y;
scanf("%d %d", &x, &y);
Link[x].push_back(y);
Link[y].push_back(x);
}
for(int i = 1; i <= n; ++i) s[i].rt = Sg::nil;
dfs(1, 0);
for(int i = 1; i <= n; ++i) printf("%lld ", ret[i]);
return 0;
}
}
namespace DSU_on_tree {
LL ans[N], bucket[N], mx, sum;
int sz[N], gx[N], col[N];
vector <int> Link[N];
int n;
void getson(int u, int fx) {
sz[u] = 1;
int mx = 0, p = 0;
for(auto v : Link[u]) {
if(v == fx) continue;
getson(v, u);
sz[u] += sz[v];
if(sz[v] > mx) mx = sz[v], p = v;
}
if(p) gx[p] = 1;
}
void dfs(int u, int fx, int p) {
if(++bucket[col[u]] > mx) mx = bucket[col[u]], sum = col[u];
else if(bucket[col[u]] == mx) sum += col[u];
for(auto v : Link[u]) if(v != fx && v != p) dfs(v, u, p);
}
void init(int u, int fx) {
--bucket[col[u]];
for(auto v : Link[u]) if(v != fx) init(v, u);
}
void dsu(int u, int fx) {
int p = 0;
for(auto v : Link[u]) {
if(v == fx) continue;
if(!gx[v]) dsu(v, u), init(v, u), sum = mx = 0;
else p = v;
}
if(p) dsu(p, u);
dfs(u, fx, p);
ans[u] = sum;
}
signed main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("Ans.txt", "w", stdout);
#endif
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", col + i);
for(int i = 1, x, y; i < n; ++i) {
scanf("%d %d", &x, &y);
Link[x].push_back(y), Link[y].push_back(x);
}
getson(1, 0);
dsu(1, 0);
for(int i = 1; i <= n; ++i) printf("%lld ", ans[i]);
return 0;
}
}
//signed main() { return SegmentTree_Combination::main(); }
signed main() { return DSU_on_tree::main(); }
标签:Node,val,int,text,sum,fx,gelral,CF600E,void 来源: https://www.cnblogs.com/Doge297778/p/16611139.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。