zoukankan      html  css  js  c++  java
  • AtCoder Grand Contest 009 D:Uninity

    题目传送门:https://agc009.contest.atcoder.jp/tasks/agc009_d

    题目翻译

    定义只有一个点的树权值为(0),若干棵(可以是(0)棵)权值为(k)的树任选一个点向一个单独的结点(v)连边,新生成的树的权值为(k+1)。显然对于一棵树他的权值是一个范围([x,inf)),求给定的树的权值范围的最小值。(nleqslant10^5)

    题解

    假设(bit[i])为以(i)为根的子树的权值。那么任何一对权值相同的点在树上的简单路径上都会有一个点权值大于他们的权值。

    我们钦点一个权值(k)对于一个点是待处理的当且仅当:这个点权值为(k)或者这个点子树内某一点权值为(k)并且到这个点的路径上没有任何一点大于(k)

    如果一个点有两棵子树有(k)这个待处理权值那么这个点权值就必须大于(k)

    如果只有一个子树有(k)这个待处理权值那么这个点权值就不能等于(k)

    根据点分治的思想最大权值不会超过(logn),所以我们可以二进制压位搞一波。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1e5+5;
    
    int n,tot,ans;
    int bit[maxn];
    int now[maxn],pre[maxn*2],son[maxn*2];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    void add(int a,int b) {
    	pre[++tot]=now[a];
    	now[a]=tot,son[tot]=b;
    }
    
    void dfs(int fa,int u) {
    	int limit=0;
    	for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    		if(v!=fa) {
    			dfs(u,v);
    			limit|=bit[u]&bit[v];
    			bit[u]|=bit[v];
    		}
    	int mx=20;
    	while(mx>=0&&(!(limit&(1<<mx))))mx--;
    	mx++;
    	while(bit[u]&(1<<mx))mx++;
    	bit[u]|=1<<mx;
    	ans=max(ans,mx),bit[u]=bit[u]>>mx<<mx;
    }
    
    int main() {
    	n=read();
    	for(int i=1;i<n;i++) {
    		int a=read(),b=read();
    		add(a,b),add(b,a);
    	}
    	dfs(0,1);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    android 从服务器获取新闻数据并显示在客户端
    Java多线程系列之:线程间的通信
    Java多线程系列之:多线程一些基本概念
    Java多线程系列之:内存可见性
    计算机基础
    tomcat系列之六:Tomcat顶层组件
    tomcat系列之五:Tomcat各个组件生命周期
    tomcat系列之四:Tomcat架构(下)
    tomcat系列之三:Tomcat架构
    tomcat系列之二:Servlet规范
  • 原文地址:https://www.cnblogs.com/AKMer/p/10214876.html
Copyright © 2011-2022 走看看