zoukankan      html  css  js  c++  java
  • [CF1446C] Xor Tree

    [题目链接]

    https://codeforces.com/contest/1446/problem/C

    [题解]

    将 "删去最少" 转化为 "保留最多" 会易于处理一些。

    题目中的限制相当于是这些数之间只有一组满足 (pos_{i} = j , pos_{j} = i)

    按二进制位建立字典树。 不妨设 (f_{i}) 表示以 (i) 为根的子树中保留最多的个数。

    (i) 没有左右儿子 , 或者是叶子的情况是很好处理的。

    (i) 有左右儿子 , 则 (f_{i} = max{f_{lc_{i}} , f_{rc_{i}}} + 1) (左边或右边取出一个最多的 , 再在另一个儿子中再取一个)

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

    [代码]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
    
    const int MN = 2e5 + 5;
    
    int rt = 1 , tot = 1 , A[MN] , N , ch[MN * 31][2];
    
    inline void insert(int val) {
    	int cur = rt;
    	for (int i = 30; i >= 0; --i) {
    		bool c = val >> i & 1;
    		if (!ch[cur][c]) ch[cur][c] = ++tot;
    		cur = ch[cur][c]; 
    	}
    }
    inline int solve(int now) {
    	if (!ch[now][0] && !ch[now][1]) return 1;
    	if (!ch[now][0]) return solve(ch[now][1]);
    	if (!ch[now][1]) return solve(ch[now][0]);
    	return max(solve(ch[now][0]) , solve(ch[now][1])) + 1;
    }
    
    int main() {
    	 
     	 scanf("%d" , &N);
     	 for (int i = 1; i <= N; ++i) {
     	 	 scanf("%d" , &A[i]);
     	 	 insert(A[i]);
    	 }
    	 printf("%d
    " , N - solve(rt));
         return 0;
    }
  • 相关阅读:
    「WC2021」表达式求值
    [补]「WC2021」括号路径
    「CEOI2020」星际迷航
    「CEOI2018」斐波那契表示法
    CF913F
    CF1017G The Tree
    NOI2020 超现实树
    LOJ 6714 Stupid Product
    LOJ 575. 不等关系
    CF1267G
  • 原文地址:https://www.cnblogs.com/evenbao/p/14033836.html
Copyright © 2011-2022 走看看