zoukankan      html  css  js  c++  java
  • CodeForces600E Lomsat gelral 线段树合并


    从树上启发式合并搜出来的题

    然而看着好像线段树合并就能解决???

    那么就用线段树合并解决吧

    维护(max, sum)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可

    复杂度(O(n log n))


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
    
    #define gc getchar
    inline int read() {
    	int p = 0, w = 1; char c = gc();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = gc(); }
    	while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
    	return p * w;
    }
    
    const int sid = 4e5 + 5;
    
    int n, cnp, id;
    ll sum[sid], ans[sid];
    int rt[sid], ls[sid], rs[sid], mx[sid], c[sid];
    int cap[sid], nxt[sid], node[sid];
    
    inline void addedge(int u, int v) {
    	nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
    }
    
    inline void insert(int &o, int l, int r, int v) {
    	o = ++ id;
    	mx[o] = 1; sum[o] = v;
    	if(l == r) return;
    	int mid = (l + r) >> 1;
    	if(v <= mid) insert(ls[o], l, mid, v);
    	else insert(rs[o], mid + 1, r, v);
    }
    
    inline void upd(int o) {
    	int lc = ls[o], rc = rs[o];
    	mx[o] = mx[lc]; sum[o] = sum[lc];
    	if(mx[rc] == mx[o]) sum[o] += sum[rc];
    	else if(mx[rc] > mx[o]) mx[o] = mx[rc], sum[o] = sum[rc];
    }
    
    inline int merge(int x, int y, int l, int r) {
    	if(!x || !y) return x + y;
    	if(l == r) { mx[x] += mx[y]; return x; }
    	int mid = (l + r) >> 1;
    	ls[x] = merge(ls[x], ls[y], l, mid);
    	rs[x] = merge(rs[x], rs[y], mid + 1, r);
    	upd(x);  
    	return x;
    }
    
    #define cur node[i]
    inline void dfs(int o, int fa) {
    	insert(rt[o], 1, n, c[o]);
    	for(int i = cap[o]; i; i = nxt[i]) 
    	if(cur != fa) {
    		dfs(cur, o);
    		rt[o] = merge(rt[o], rt[cur], 1, n);
    	}
    	ans[o] = sum[rt[o]];
    }
    
    int main() {
    	n = read();
    	rep(i, 1, n) c[i] = read();
    	rep(i, 2, n) {
    		int u = read(), v = read();
    		addedge(u, v); addedge(v, u);
    	}
    	dfs(1, 0);
    	rep(i, 1, n) printf("%lld ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    Laravel schema构建器列类型
    wkhtmltopdf docker + java(环境搭建及一些坑)
    dockerfile,仓库,私有仓库流程(转载)
    wkhtmltopdf参数详解及精讲使用方法(转载)
    传统前端项目中进行模块化编程并引入使用vue、elementui 前端
    vue3 + vuex4 实践 前端
    elementplus 原生开发 日期国际化语言 前端
    Vite2.0打包elementplus UI报错 前端
    vue3 Vetur报错:has no default export 组件没导出 前端
    windows版的HbuilderX连接iPad真机测试(uniapp)
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10145791.html
Copyright © 2011-2022 走看看