Codeforces Round #613 (Div. 2) D. Dr. Evil Underscores

题目:http://codeforces.com/contest/1285/problem/D
思路:从高位往低位建 \(01\;trie\) 树,从高位 dfs
当只有一个分支,当前位为 \(0\),填法唯一;
当有两个分支,当前位为 \(1\),填法不唯一,则返回较小值;

#include<bits/stdc++.h>

using namespace std;

const int N=1e5+5;

int n;
int trie[N*31][2];
int cnt;

void insert(int a)
{
    int pre=0;
    for(int i=30;i>=0;i--)
    {
        int now=(a>>i)&1;
        if(!trie[pre][now]) trie[pre][now]=++cnt;
        pre=trie[pre][now];
    }
}
int dfs(int pre,int t,int res)
{
    if(t==-1) return res;
    if(trie[pre][0]&&!trie[pre][1]) return dfs(trie[pre][0],t-1,res);
    else if(!trie[pre][0]&&trie[pre][1]) return dfs(trie[pre][1],t-1,res);
    return min(dfs(trie[pre][0],t-1,res+(1<<t)),dfs(trie[pre][1],t-1,res+(1<<t)));
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int a;
        cin>>a;
        insert(a);
    }
    cout<<dfs(0,30,0)<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/c4Lnn/p/12178902.html

时间: 2024-08-29 14:25:25

Codeforces Round #613 (Div. 2) D. Dr. Evil Underscores的相关文章

Codeforces Round #613 (Div. 2) D - Dr. Evil Underscores(思维,位运算)

?? ?? ?? 题意:对于一个数组,求一个数字与数组每个元素异或之后的最大值最小,求这个最大值 又是位运算,,题目给出数组元素范围在2^30以内,二进制最多30位,从最高位开始贪心,如果此位置的数组元素有的是1有的是0,最后肯定取1,否则取0,还有就是分组讨论,因为每个bit位只能满足原数组中一部分元素异或后为1 #define int ll vector<int>a; int solve(vector<int>v,int bit) { if(bit<=0||v.size(

Codeforces Round #613 (Div. 2)

https://codeforces.com/contest/1285 A - Mezo Playing Zoma 题意:按一系列的"LR"键,其中一些键可能被忽略执行,求最后分布的位置数量. 题解:肯定是最左和最右夹着的区间,所以统计最左的和最右的位置.最后会发现恰好就是n+1. B - Just Eat It! 题意:问是否有一段subsegment的和>=全体的和,这个subsegment不能取全体. 题解:这题里的subsegment要去掉非空前缀,或者去掉非空后缀,或者

Codeforces Round #613 (Div. 2)D(贪心,分治)

构造两颗深度为30的字典树(根节点分别是0和1),结点只有0和1,从根节点向下DFS,贪心取答案. 1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 vector<int>a; 5 int dfs(vector<int>b,int x){ 6 if(x<0||b.size()==0)//30位都枚举完毕或当前向量中没有数字就中止 7 return 0;

Codeforces Round #613 (Div. 2) B. Just Eat It!

Link 题意: 求最大区间和所在区间是不是 \(1 \sim n\) 思路: 设 \(dp[i]\) 是以 \(i\) 为右端的最大区间和 \(dp[i]=max(dp[i-1]+a[i],a[i])\) 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5;; int n; ll a[N]; int main() { ios::sync_with_stdio(fals

Dr. Evil Underscores

D - Dr. Evil Underscores 参考:Codeforces Round #613 (Div. 2) Editorial 其实比赛的时候就已经想到了基本上一样的解法,可是最后还是没有写出来... 具体思路就是分治,在二进制中,如果\(a_1{\sim}a_n\),在该位上既有1又有0,说明这一位上的数是躲不掉的,那么这一位上肯定是1,所以在返回的数里加一个1<<i,而对于后面的数则取最小值即可min(dfs(i-1, v0), dfs(i-1, v1))+(1 <<

Codeforces Round #356 (Div. 2) [Codeforces680]

此处有目录↑ Codeforces Round #356(Div. 2):http://codeforces.com/contest/680 A. Bear and Five Cards (贪心) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A little bear Limak plays a game. He has

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我