首页 > 其他分享 >关于此题E - Maximize XOR(Atcoder ABC 386)搜索技巧的一些总结

关于此题E - Maximize XOR(Atcoder ABC 386)搜索技巧的一些总结

时间:2025-01-02 12:29:26浏览次数:1  
标签:Atcoder ABC kk sum 个数 long 异或 搜索 386

传送门
题目要求n个数中选k个数异或起来最大,我们想到字典树中最大异或和这一经典问题,但是很明显字典树只能解决任选两个数的最大异或,而此题是任选k个,那我们走投无路只能考虑爆搜。
首先可以很容易写出一个暴力的搜索:

void dfs1(long long pos,long long sum,long long kk) {
    if(kk == 0) {
        ans = max(ans,sum);
        return;
    }
    if(pos == n+1) return;
    for(long long i = pos;i <= n;i++)
        dfs1(i+1,sum ^ a[i],kk-1);
}

但是这样肯定是会T爆的,我们注意到,当k取得值比较大的时候,复杂度就已经接近\(2^{n}\)了,而这是肯定无法接受的。
如果做过最大异或和问题,那么肯定有一个性质是牢记于心的:一个数异或两遍另一个数还等于它本身(结合异或运算的法则很好推
那么我们想,当k非常大的时候,是不是可以把问题转化成:我们知道n个数异或起来的值,想从中剔除掉n-k个数使得结果最大,而此处的“剔除”操作,是不是和前面的“增加”操作其实都是异或操作(不像是加减操作 增加和剔除是不同的符号),那么我们只需要进行分类讨论:
当$k ≤ n-k: $只需要爆搜即可

当$k > n-k: $我们就相当于把初始值设成tot(就是所有数的异或和),然后同样的用上面的搜索函数,将kk(代表从n个数中找kk个数)从k改成n-k即可,因为此时想象成挑n-k个剔除。
得益于异或操作的这一性质,这道题被巧妙解决。

再顺带一提,关于搜索程序的写法,我一开始的写法是:

void dfs1(long long num,long long sum,long long kk) {
    if(num == kk) {
        ans = max(ans,sum);
        return;
    }
    for(long long i = 1;i <= n;i++) {
        if(!vis[i]) {
            vis[i] = 1;
            dfs1(num+1,sum ^ a[i],kk);
            vis[i] = 0;
        }
    }
}

然而这样就会T爆。原因是重复搜索了很多次相同的k(或n-k)个数,完全不需要在当前位置的时候还回头看,这样会大大浪费时间复杂度。所以搜索的写法也很重要

标签:Atcoder,ABC,kk,sum,个数,long,异或,搜索,386
From: https://www.cnblogs.com/lwiwi/p/18647401

相关文章

  • 题解:AT_abc386_d [ABC386D] Diagonal Separation
    分析题面,发现题目求的是是否存在一个白点被\((1,1)\)和任意一个黑点围成的矩形内。先将所有黑点按\(x\)坐标排序。枚举所有的白点。找到所有横坐标不比该白点横坐标小的所有黑点的纵坐标的最大值所属点。如果该点的纵坐标小于该白点的纵坐标:(蓝点代表题目中的白点,红点......
  • AtCoder Beginner Contest 386(补题)
    AtCoderBeginnerContest386C-Operate1https://atcoder.jp/contests/abc386/tasks/abc386_c思路简单的条件判断题代码#include<bits/stdc++.h>typedefstd::pair<int,int>pii;#defineINF0x3f3f3f3f#defineMOD998244353usingi64=longlong;cons......
  • WPF使用TreeView和TabControl控件jian实现菜单的选择和切换
    一、页面添加TreeView和TabControl控件1.在MainWindow.xaml页面上添加TreeView控件,设置ItemsSource属性为ViewModel中的TreeList属性,添加<TreeView.ItemTemplate>,在该节点下添加<HierarchicalDataTemplate>,绑定ViewModel中的TreeList下子项中的Children属性,菜单名称绑定Header......
  • atcoder ABC385 部分题解
    G-CountingBuildings简要题义一个排列的\(L(P)\)为\(\sum_{i=1}^n[premax(i)=P_i]\),即前缀最大值为自身的位置数,\(R(P)\)同理为后缀最大值。有多少个排列使得\(L(P)-R(P)=k\)题解假设\(n,k\)是同阶的。我们从\(n\)到\(1\)依次插入数,考虑朴素的DP:设\(f_{i,k......
  • AtCoder Beginner Contest 386 赛后总结
    赛时A-D。菜。A-C模拟即可。D先检查一下竖着的一列有没有出现:白黑或者黑白黑的情况。有的话一定不行。因为每个白点的右下角一定都得是白的,就相当于对下面的行数取后缀最小值,这个可以使用差分实现。点击查看代码#include<bits/stdc++.h>#definelllonglong#def......
  • CDS标准视图:ABC标识文本 I_ABCIndicatorText
    视图名称:ABC标识文本I_ABCIndicatorText视图类型:基础视图视图代码:点击查看代码@EndUserText.label:'ABCIndicator-Text'@VDM.viewType:#BASIC@AbapCatalog.sqlViewName:'IABCINDICTEXT'@AbapCatalog.compiler.compareFilter:true@Analytics:{dataExtraction.......
  • AT_abc237_g [ABC237G] Range Sort Query 题解
    题目传送门前置知识珂朵莉树/颜色段均摊解法观察到只有\(=x\)的位置才是重要的,而其他位置上的数具体是什么并不重要,我们只需要关注其大小关系。第一遍将\(\gex\)的数看做\(1\),将\(<x\)的数看做\(0\)。第二遍将\(>x\)的数看做\(1\),将\(\lex\)的数看做\(1\)。......
  • [题解](更新中)AtCoder Beginner Contest 386(ABC386) A~E
    A-FullHouse2容易发现,答案为Yes\(\iff\)输入中恰好出现了\(2\)种不同的数,可以用set等数据结构来计算不同元素的个数。点击查看代码#include<bits/stdc++.h>usingnamespacestd;set<int>se;signedmain(){ for(inti=1,a;i<=4;i++){ cin>>a; se.insert(a); } c......
  • AtCoder DP Contest(刷题记录)
    A-Frog1题意:给定\(n\)个石头,第\(i\)个石头的高度为\(h_i\).现在要求小青蛙从\(1\)号石头跳到\(n\)号石头,每次小青蛙可以选择从\(i\)号石头跳到\(i+1\)或\(i+2\)号石头,代价是起跳点与落点的高度差的绝对值。询问你最小代价。解法:\(dp[i]\)表示小青蛙跳到第号石头时的最小代......
  • [ABC220H] Security Camera(FWT)
    题意给定一张\(n\)点\(m\)边的无向图,每个点都有权值0,你现在要将一部分点的权值变成1,使得边的两端的权值的按位或和为1的边的数量为偶数,求方案数。\(n\le40\)分析由于我是来学FWT的,所以不考虑线性代数。不难发现题意可以转化成求边的两端权值都为0的边的数量为偶......