zoukankan      html  css  js  c++  java
  • CF1009F Dominant Indices 长链剖分

    题目传送门

    https://codeforces.com/contest/1009/problem/F

    题解

    长链剖分的板子吧。

    (dp[x][i]) 表示 (x) 的子树中的深度为 (i) 的点的个数。

    那么转移的时候就是一般的长链剖分指针移位来维护。

    然后就可以在转移的时候通过被转移的那一位被更新的值来更新当前这个点的最优解就可以了。


    时间复杂度 (O(n))

    #include<bits/stdc++.h>
    
    #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
    #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define fi first
    #define se second
    #define pb push_back
    
    template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
    template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
    
    typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
    
    template<typename I> inline void read(I &x) {
    	int f = 0, c;
    	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    	x = c & 15;
    	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    	f ? x = -x : 0;
    }
    
    const int N = 1e6 + 7;
    
    int n;
    int len[N], son[N];
    int a[N], *dp[N], *now, mx[N];
    
    struct Edge { int to, ne; } g[N << 1]; int head[N], tot;
    inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
    inline void adde(int x, int y) { addedge(x, y), addedge(y, x); }
    
    inline void dfs1(int x, int fa = 0) {
    	len[x] = 1;
    	for fec(i, x, y) if (y != fa) dfs1(y, x), smax(len[x], len[y] + 1) && (son[x] = y);
    }
    
    inline void init(int x) { dp[x] = now, now += len[x]; }
    
    inline void dfs2(int x, int fa = 0) {
    	if (son[fa] != x) init(x);
    	dp[x][0] = 1;
    	if (son[x]) dp[son[x]] = dp[x] + 1, dfs2(son[x], x), mx[x] = mx[son[x]] + 1;
    	if (dp[x][mx[x]] == 1) mx[x] = 0;
    	for fec(i, x, y) if (y != fa && y != son[x]) {
    		dfs2(y, x);
    		for (int i = 0; i < len[y]; ++i) if (i + 1 < len[x]) {
    			dp[x][i + 1] += dp[y][i];
    			if (dp[x][i + 1] > dp[x][mx[x]] || (dp[x][i + 1] == dp[x][mx[x]] && i + 1 < mx[x])) mx[x] = i + 1;
    		}
    	}
    }
    
    inline void work() {
    	dfs1(1);
    	now = a;
    	dfs2(1);
    	for (int i = 1; i <= n; ++i) printf("%d
    ", mx[i]);
    }
    
    inline void init() {
    	read(n);
    	int x, y;
    	for (int i = 1; i < n; ++i) read(x), read(y), adde(x, y);
    }
    
    int main() {
    #ifdef hzhkk
    	freopen("hkk.in", "r", stdin);
    #endif
    	init();
    	work();
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    linux tftp 服务
    AtomicInteger
    深入理解JVM(三)——垃圾收集策略具体解释
    Android 虚拟现实(virtual reality)入门指南
    Java千百问_05面向对象(005)_接口和抽象类有什么差别
    postman发送json格式的post请求
    什么是Session分布式共享
    如何设计一个单点登录系统(3)?
    如何设计一个单点登录系统(2)?
    如何设计一个单点登录系统(1)?
  • 原文地址:https://www.cnblogs.com/hankeke/p/cf1009f.html
Copyright © 2011-2022 走看看