• [Codeforces Round #613 (Div. 2)]


    Problem

    Codeforces 题目地址

    洛谷 题目地址

    Solution

    这个题目的一种解法 ———— Tire上树形dp。 (第一次听说这种做法) 相信听到这个做法后,你大概就知道怎么做了。

    首先先把所有数字建成一棵 Tire,根节点的儿子表示第 30 位,然后依次类推(从高位往低位建)。

    假设(u) 的儿子表示的是第 (k) 位,那么点 (u) 的儿子的意义就是:左儿子这边的数第 (k) 位上是 (1),反之,右儿子这边的数第 (k) 位上是 (0)

    如果点 (u) 只有一个儿子,那么我们需要构造的数 (x) 的第 (k) 位就选这个儿子代表的数 ((0/1)),因为这样异或后就可以抵消。

    如果点 (u) 有两个儿子,那么我们需要构造的数 (x) 的第 (k) 位选什么都会有 ((1<<k)) 的影响,这时我们要使总答案最小就要取 (min{ls(),rs()})

    实际做的时候并不要把树建出来。

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    int n;
    vector<int> a;
    int Solve(vector<int> p,int K) {
    	if(p.size()==0 || K<0) return 0;
    	vector<int> p1,p2;
    	for(int i=0;i<p.size();++i) {
    		if(p[i] & (1<<K)) p1.push_back(p[i]);
    		else p2.push_back(p[i]);
    	}
    	if(p1.size() == 0) return Solve(p2,K-1);
    	else if(p2.size() == 0) return Solve(p1,K-1);
    	else return (1<<K) + min(Solve(p1,K-1),Solve(p2,K-1));
    }
    int main()
    {
    	n = read();
    	for(int i=1,x;i<=n;++i) {
    		x = read();
    		a.push_back(x);
    	}
    	printf("%d
    ",Solve(a,30));
    	return 0;
    }
    

    Summary

    Trie上树形dp,经典题。

  • 相关阅读:
    AVA 源码解读-规则逻辑
    gojs 如何实现虚线(蚂蚁线)动画?
    谷歌复制接口json
    vue拼图动画Demo
    如何获取一个类的全名
    `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js(vue报错)
    Jquery通知组件
    字典树 (Trie Tree)
    [CPP] 虚函数与纯虚函数
    格雷码
  • 原文地址:https://www.cnblogs.com/BaseAI/p/12181934.html
Copyright © 2020-2023  润新知