zoukankan      html  css  js  c++  java
  • 「CF 600E」 Lomsat gelral

    题目链接

    戳我

    (Describe)

    给出一棵树,每个节点有一个颜色,求每个节点的子树中颜色数目最多的颜色的和。

    (Solution)

    这道题为什么好多人都写的是启发式合并,表示我不会啊.

    这道题不是可以用线段树合并吗?将每个子节点看做一个线段树,维护两个值一个颜色的数目最大值,一个是最大颜色的和,然后不断从儿子向父亲合并即可.

    (Code)

    #include<bits/stdc++.h>
    #define int long long 
    #define rg register
    using namespace std;
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9')  f= (c=='-')?-1:1,c=getchar();
        while(c>='0'&&c<='9')  x=x*10+c-48,c=getchar();
        return f*x;
    }
    struct node {
    	int to,next;
    }a[2000011];
    struct node1{
    	int ch[2],sum,rt,maxx;
    }t[2000011];
    int head[200011],cnt,x,y,n,c[200011];
    void add(int x,int y){
    	a[++cnt].to=y;
    	a[cnt].next=head[x];
    	head[x]=cnt;
    }
    int b[200011],tot;
    void add(int &rt,int l,int r,int c){
    	rt=++tot;
    	t[rt].maxx=1,t[rt].sum=c;
    	if(l==r)
    		return ;
    	int mid=(l+r)>>1;
    	if(c<=mid)
    		add(t[rt].ch[0],l,mid,c);
    	else add(t[rt].ch[1],mid+1,r,c);
    }
    void pushup(int x){
    	int fx=t[x].ch[0],fy=t[x].ch[1];
    	if(t[fx].maxx==t[fy].maxx)
    		t[x].sum=t[fx].sum+t[fy].sum,t[x].maxx=t[fx].maxx;
    	else if(t[fx].maxx>t[fy].maxx)
    		t[x].sum=t[fx].sum,t[x].maxx=t[fx].maxx;
    	else t[x].sum=t[fy].sum,t[x].maxx=t[fy].maxx;
    }
    int join(int x,int y,int l,int r){
    	if(!x||!y)
    		return x+y;
    	int mid=(l+r)>>1;
    	if(l==r){
    		t[x].maxx+=t[y].maxx;
    		return x;
    	}
    	t[x].ch[0]=join(t[x].ch[0],t[y].ch[0],l,mid);
    	t[x].ch[1]=join(t[x].ch[1],t[y].ch[1],mid+1,r);
    	pushup(x);
    	return x;
    }
    void dfs(int x,int fa){
    	add(t[x].rt,1,n,b[x]);
    	for(int i=head[x];i;i=a[i].next){
    		int v=a[i].to;
    		if(v==fa)
    			continue;
    		dfs(v,x);
    		t[x].rt=join(t[x].rt,t[v].rt,1,n);
    	}
    	c[x]=t[t[x].rt].sum;
    }
     main(){
    	n=read();
    	for(int i=1;i<=n;i++)
    		b[i]=read();
    	for(int i=1;i<n;i++)
    		x=read(),y=read(),add(x,y),add(y,x);
    	dfs(1,0);
    	for(int i=1;i<=n;i++)
    		printf("%I64d ",c[i]);
    }
    
  • 相关阅读:
    java之 Timer 类的使用以及深入理解
    关于百度Editor富文本编辑器 自定义上传位置
    BufferedInputStream/BufferedOutputStream
    ByteArrayInputStream/ByteArrayOutputStream 学习
    Android之ViewPager 第二课
    Android之ViewPager 第一课
    内存四区模型
    变量的本质
    数据类型的本质
    File、Blob、ArrayBuffer等文件类的对象有什么区别和联系
  • 原文地址:https://www.cnblogs.com/hbxblog/p/10313414.html
Copyright © 2011-2022 走看看