zoukankan      html  css  js  c++  java
  • CF600E Lomsat gelral 【线段树合并】

    题目链接

    CF600E

    题解

    容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可
    对于每个节点合并一下两个子节点的信息
    要注意叶子节点信息的合并和非叶节点信息的合并是不一样的

    由于合并不比逐个插入复杂度高,所以应是(O(nlogn))

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 100005,maxm = 8000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    LL sum[maxm],ans[maxn];
    int ls[maxm],rs[maxm],mx[maxm],cnt;
    int n,c[maxn],fa[maxn],rt[maxn];
    int h[maxn],ne = 1;
    struct EDGE{int to,nxt;}ed[maxn << 1];
    inline void build(int u,int v){
    	ed[++ne] = (EDGE){v,h[u]}; h[u] = ne;
    	ed[++ne] = (EDGE){u,h[v]}; h[v] = ne;
    }
    inline void upd(int u){
    	sum[u] = 0;
    	if (mx[ls[u]] >= mx[rs[u]]){
    		mx[u] = mx[ls[u]];
    		sum[u] += sum[ls[u]];
    	}
    	if (mx[rs[u]] >= mx[ls[u]]){
    		mx[u] = mx[rs[u]];
    		sum[u] += sum[rs[u]];
    	}
    }
    void modify(int& u,int pre,int l,int r,int pos){
    	u = ++cnt; ls[u] = ls[pre]; rs[u] = rs[pre];
    	if (l == r){mx[u] = mx[pre] + 1; sum[u] = l; return;}
    	int mid = l + r >> 1;
    	if (mid >= pos) modify(ls[u],ls[pre],l,mid,pos);
    	else modify(rs[u],rs[pre],mid + 1,r,pos);
    	upd(u);
    }
    int merge(int u,int v,int l,int r){
    	if (!u) return v;
    	if (!v) return u;
    	int t = ++cnt,mid = l + r >> 1;
    	if (l == r){
    		mx[t] = mx[u] + mx[v];
    		sum[t] = l;
    		return t;
    	}
    	ls[t] = merge(ls[u],ls[v],l,mid);
    	rs[t] = merge(rs[u],rs[v],mid + 1,r);
    	upd(t);
    	return t;
    }
    void dfs(int u){
    	modify(rt[u],rt[u],1,n,c[u]);
    	Redge(u) if ((to = ed[k].to) != fa[u]){
    		fa[to] = u; dfs(to);
    		rt[u] = merge(rt[u],rt[to],1,n);
    	}
    	ans[u] = sum[rt[u]];
    }
    int main(){
    	n = read();
    	REP(i,n) c[i] = read();
    	for (int i = 1; i < n; i++) build(read(),read());
    	dfs(1);
    	REP(i,n) printf("%lld ",ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    Ftp、Ftps与Sftp之间的区别
    Previous Workflow Versions in Nintex Workflow
    Span<T>
    .NET Core 2.0及.NET Standard 2.0 Description
    Announcing Windows Template Studio in UWP
    安装.Net Standard 2.0, Impressive
    SQL 给视图赋权限
    Visual Studio for Mac中的ASP.NET Core
    How the Microsoft Bot Framework Changed Where My Friends and I Eat: Part 1
    用于Azure功能的Visual Studio 2017工具
  • 原文地址:https://www.cnblogs.com/Mychael/p/9210792.html
Copyright © 2011-2022 走看看