首页 > 其他分享 >Educational Codeforces Round 2 E Lomsat gelral 线段树合并

Educational Codeforces Round 2 E Lomsat gelral 线段树合并

时间:2023-03-15 23:13:13浏览次数:61  
标签:std Educational int tr Codeforces gelral cnt include define

题目链接

大致题意

给你一棵有n个点的树,树上每个节点都有一种颜色ci(ci≤n),让你求每个点子树出现最多的颜色/编号的和
记性不好,主要是为了防止自己忘掉,今天和队友合作写题的时候甚至有点想不起来kmp是干嘛的,在博客园标记一下这个题目的解析和做法

关于什么时候能用线段树合并

假设我们会加入k个点,那么时间复杂度和空间复杂度都会是O(klogk)
做法和证明如下链接
线段树合并时间复杂度和空间复杂度证明

#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <stack>
#include <queue>
#include <numeric>
#include <cassert>
#include <bitset>
#include <cstdio>
#include <vector>
#include <unordered_set>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <deque>
#include <tuple>
#include <array>
 
#define all(a) a.begin(), a.end()
#define cnt0(x) __builtin_ctz(x)
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define cntone(x) __builtin_popcount(x)
#define db double
#define fs first
#define ls(x) (tr[x].l)
#define rs(x) (tr[x].r)
#define cnt(x) (tr[x].cnt)
#define mx(x) (tr[x].v)
#define se second
#define AC main(void)
#define HYS std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;

const long double eps = 1e-9;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10, M = 4e5 + 10;
int n , m, p;

int d1[] = {0, 0, 1, -1};
int d2[] = {1, -1, 0, 0};

int h[N], ne[N << 1], w[N << 1], e[N << 1], root[N];
int tot, idx;
ll ans[N];

struct node{
	int l, r;
	ll v;
	int cnt;
}tr[N * 20];//最多添加1e5个点 每个点最多log层 所以乘以一个log的空间

void pushup(int u){
	if(tr[ls(u)].cnt > tr[rs(u)].cnt){
		tr[u].cnt = tr[ls(u)].cnt;
		tr[u].v = tr[ls(u)].v;
	}
	else if(tr[ls(u)].cnt < tr[rs(u)].cnt){
		tr[u].cnt = tr[rs(u)].cnt;
		tr[u].v = tr[rs(u)].v;
	}else{
		tr[u].cnt = tr[ls(u)].cnt;
		tr[u].v = tr[ls(u)].v + tr[rs(u)].v;
	}
}

inline void add(int a, int b){
	ne[idx] = h[a], e[idx] = b, h[a] = idx ++;
}

//线段树合并操作 当没有一个儿子的时候会O1否则logn
inline int merge(int p, int q, int L, int R){
	if(!p)	return q;
	if(!q)	return p;
	if(L == R){
		tr[p].cnt += tr[q].cnt;
		tr[p].v = L;
		return p;
	}	
	int mid = L + R >> 1;
	tr[p].l = merge(tr[p].l, tr[q].l, L, mid);
	tr[p].r = merge(tr[p].r, tr[q].r, mid + 1, R);
	pushup(p);
	return p;
}

inline void update(int u, int L, int R, int x, int sum){
	if(L == R){
		tr[u].cnt += sum;
		tr[u].v = L;
		return ;
	}
	int mid = L + R >> 1;
	if(x <= mid){
		if(!tr[u].l)	tr[u].l = ++ tot;
		update(tr[u].l, L, mid, x, sum);
	}	
	else{
		if(!tr[u].r)	tr[u].r = ++ tot;
		update(tr[u].r, mid + 1, R ,x, sum);
	} 
	pushup(u);
}

inline void dfs(int u, int fa){
	root[u] = ++ tot;
	for(int i = h[u]; ~i; i = ne[i]){
		int j = e[i];
		if(fa == j)	continue;
		dfs(j, u);
		merge(root[u], root[j], 1, n);
	}
	update(root[u], 1, n, w[u], 1);
	ans[u] = tr[root[u]].v;
}

inline void solve(){
	std::cin >> n;
	memset(h, -1, sizeof h);
	for(int i = 1; i <= n; i ++)	std::cin >> w[i];
	for(int i = 1; i < n; i ++){
		int a, b;
		std::cin >> a >> b;
		add(a, b), add(b, a);
	}
	
	dfs(1, -1);
	
	for(int i = 1; i <= n; i ++)	std::cout << ans[i] << ' ';
}

signed AC{
   	HYS
   	
	int _ = 1;
	//std::cin >> _;
	while(_ --)
        solve();

    return 0;
}

标签:std,Educational,int,tr,Codeforces,gelral,cnt,include,define
From: https://www.cnblogs.com/qdhys/p/17220518.html

相关文章

  • Codeforces Round 855 (Div. 3)
    之前立下了一个flag,每个有空的下午做一套CF来增长智商。题目地址G.Symmetree问题的本质如何快速比对两个子树是否相同。考虑树hash。这里采用的是主流的AHU算法(安徽......
  • Codeforces Round 857 (Div. 2) A. Likes
    linkCode//#include<bits/stdc++.h>#include<iostream>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<cmath>#include......
  • Educational Codeforces Round 105 (Rated for Div
    EducationalCodeforcesRound105(RatedforDiv.2)ABCString给定一个字符串只有A、B和C构成。要求替换A、B、C为')'和'(',并且相同字母替换的是一样的,使得字符串变......
  • Codeforces Round 713 (Div
    CodeforcesRound713(Div.3)A-BPalindrome给定字符串只含有\('?'\'0'\'1'\),给定字符串中1的个数\(a\)和0的个数\(b\),你需要将?替换成0或1,使得该字符串变成回文......
  • Codeforces Round 857 (Div. 2)
    比赛地址做到F心态崩了,自然不会去做G.F考虑最终路径一定是这样的1到x节点在x处攒够路费再到n.后者可以通过从n跑dij来求最短路。考虑前者需要求从1~x的最小代价。......
  • CodeForces 1147F Zigzag Game
    洛谷传送门CF传送门很有意思的题。考虑若无边权的限制则B必胜,不妨猜想有了限制之后仍然是B必胜。假设A选了I(若A选了D可以边权取相反数),若B走了\((a,b)\)......
  • Codeforces Round 857 (Div. 2)
    题目链接A核心思路读懂题目也就不难了。//Problem:A.Likes//Contest:Codeforces-CodeforcesRound857(Div.2)//URL:https://codeforces.com/contest/180......
  • Codeforces比赛规则梳理
    1、排名div选手们按Rating以1700为界划分为Div.1和Div.2两类,Div.1的比赛较难,Div.1的ABC三题会和Div.2的CDE三题相同。每次比赛结束后Rating都会依据此前各个选手的Rating和......
  • Codeforces Round #666 (Div. 2)D. Stoned Game(博弈问题)
    problemT和HL玩游戏,n堆石头,玩家轮流在石堆中选择一个(但不能是上一个人取的那堆)取一个石子一旦有一方不能取石头则判输solution统计所有石头数,如果总数小于mx(最多石头的一堆)......
  • Codeforces Round 857 (Div. 2)
    更好的阅读第一次进入时加载缓慢,请耐心等待。赛时降智,菜是原罪。A.Likes简单题。#include<bits/stdc++.h>usingnamespacestd;intT,n,a[11111],s[11111];intm......