To xor or not to xor 高斯消元求异或

2024-06-17 08:38
文章标签 xor 高斯消 求异

本文主要是介绍To xor or not to xor 高斯消元求异或,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目】

给你n个long long范围内的整数,你可以选取1个或多个数进行异或操作,使得结果最大,求最大的结果。

【题目分析】

真是一道好题,不是真正理解高斯消元是无法做这题的。
题意:给你n个数,可以选择任意个数异或,但是要使得最后的异或值最大。
我们把每个数用二进制表示,要使得最后的异或值最大,就是要让高位尽量为1,高位能不能为1就必须用高斯消元判断了。
1. 根据数的二进制表示,建立方程组的矩阵,结果那列置为1。
2. 从下往上高斯消元(高位放下面),如果该行有未被控制的变元,则该行的结果一定为1,且该变元控制该行。
3. 从该行往上依次消掉(异或)该变元。
4. 如果该行没有可以用来控制的变元,如果最后一列是0,则该行结果也为1,否则该行结果为0。这里能抱着已用来控制的变元的系数全是0,因为在第3步时就消掉该行以上此列的0了,后面0与0以后还是0。所以如果最后一列是0, 即该行方程也可以成立,故结果为1。
建立方程:
a11x1+a21x2……=d[1]
a12x1+a22x2……=d[2]
……

【代码】

#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<memory.h>
#define ll long long
using namespace std;
int equ,var;
int n;
int a[62][105];
bool vis[105];
void gauss()
{ll ans=0;int i,j,k;for(i=equ-1;i>=0;i--){ans<<=1;for(j=0;j<var;j++){if(a[i][j]&&!vis[j]){vis[j]=true;ans|=1;break;}}if(j==var){if(a[i][var]==0) ans|=1;}else{for(k=i-1;k>=0;k--){if(a[k][j]){for(int l=0;l<var+1;l++)a[k][l]^=a[i][l];}}}}// cout<<equ<<" "<<var<<"*"<<endl;cout<<ans<<endl;
}
void init()
{ll m;var=n;//n个数,所以n个未知数equ=0;int k;for(int i=0;i<n;i++){cin>>m;k=0;while(m!=0){int j=m&1;a[k++][i]=j;m>>=1;}if(k>equ) equ=k;}for(int i=0;i<equ;i++)a[i][var]=1;
}
int main()
{freopen("in.txt","r",stdin);while(scanf("%d",&n)!=EOF){memset(a,0,sizeof(a));memset(vis,false,sizeof(vis));init();gauss();}
}
【后记】

好好理解高斯消元求余的用法


下面介绍一种yy的方法(非高斯消元)(来自高老板):

【代码】

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
const int maxn=110;
LL a[maxn];
int n;
int main() {while(scanf("%d",&n)!=EOF) {for(int i=1; i<=n; i++)scanf("%lld",&a[i]);for(int i=1; i<=n; i++) {int tmp=i;for(int j=i+1; j<=n; j++)if(a[j]>a[tmp])tmp=j;swap(a[i],a[tmp]);for(int j=i+1; j<=n; j++)a[j]=min(a[j],a[i]^a[j]);}LL ans=0;for(int i=1; i<=n; i++)ans=max(ans,ans^a[i]);printf("%lld\n",ans);}return 0;
}

【后记】具体代码是做什么用的,没有看太明白。

下面是根据上面代码进行了一下优化:

【代码】

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long f[150];
int main() {int n, i, j;while(cin>>n) {for(i=0; i<n; i++)cin>>f[i];sort(f,f+n);for(i=0; i<n; i++) {for(j=i+1; j<n; j++)//if((f[i]^f[j]) <f[j])f[j]=min(f[j],f[i]^f[j]);}long long ans=0;for(i=0; i<n; i++)ans=max(ans,ans^f[i]);cout<<ans<<endl;}return 0;
}



这篇关于To xor or not to xor 高斯消元求异或的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068961

相关文章

HDU 5833 高斯消元

n个数,任选>=1个数相乘,使得乘积是完全平方数。 其实就是开关,控制灯泡。 数 ----第i个质因子p的个数%2  = {1 , 0} == 开关----第i个灯泡 = {开 , 关} 最后使得所有灯泡都是灭着的方案数 = 2^自由变元个数   全部关着的情况     ==   一个数也不选   应省去 import java.io.BufferedReader;

ABC367G-Sum of (XOR^K or 0)

第一次学会多项式的题目。 题意: n n n个数的多重集 S S S,设 S ′ ⊆ S , f ( A ) = [ ∣ A ∣ = t m , t ∈ Z ] ( X O R a i ∈ a a i ) k S' \subseteq S,f(A)=[|A| =tm,t\in Z](XOR_{a_i\in a}ai)^k S′⊆S,f(A)=[∣A∣=tm,t∈Z](XORai​∈a​ai)k

E - Xor Distances

树和 xor 有些地方 很契合🔥。。 比如树上距离。。很容易想到减去lca公共的那段。 而xor 他异或 刚好也是会抵消公共部分的。。。 题目链接 #include <bits/stdc++.h>using namespace std;#define int long long#define ll __int128_t#define ar array<int, 2>#define a

buuctf [MRCTF2020]Xor

前言:学习笔记。 32位IDA 打开。 先查找字符串 ok,反汇编不了,好吧,只能看汇编代码。 那咱用OD去做。顺便复习汇编语言 接着往下。 没看懂?那把JNZ SHORT xor.00CE10FF 给NOP掉再看看。 再走一遍。 猜测AL是否代表的是下标? CL是对应值?不确定,再走一遍。 OK,结案,程序是对应值与对应下

hiho一下第56周 高斯消元

小Ho:<吧唧><吧唧><吧唧> 小Hi:小Ho,你还吃呢。想好了么? 小Ho:肿抢着呢(正想着呢)...<吞咽>...我记得这个问题上课有提到过,应该是一元一次方程组吧。 我们把每一件商品的价格看作是x[1]..x[n],第i个组合中第j件商品数量记为a[i][j],其价格记作y[i],则可以列出方程式: a[1][1] * x[1] + a[1][2] * x[2] + ... +

poj 1222 EXTENDED LIGHTS OUT (高斯消元解异或方程组 开关问题)

近距离观摩今天北京站的比赛,向志愿者学姐要了一份题目,看了看H题; 因为数据被弱化,瞬间就想到了背包; 就先研究下标准解法——异或方程组; 下面为转载文: 题意:有一个5*6的矩阵,每个位置都表示按钮和灯,1表示亮,0表示灭。每当按下一个位置的按钮,它和它周围灯的状态全部翻转,问在这样的一个方阵中按下哪些按钮可以把整个方阵都变成灭的,这时1表示按了,0表示没按。 以下

poj1681 高斯消元+dfs枚举

wa  N多次后,终于把高斯消元的模板给弄出来了,并且精简了许多。 用dfs枚举变元比二进制枚举变元简单多了。 (也终于明白 变元代表只得解的个数。) 上模板。 #include <iostream>#include <algorithm>using namespace std;int a[400][400];int ans[400],x[400];//ans[]用于记录哪几种

poj1222 枚举 和 高斯消元

接触开关问题,最先的方法是枚举。然后接触到了更加高深的高斯消元。 高斯消元的思想:把一个全部熄灭的矩阵经过一系列开关后得到初始的状态。 具体分析可参照 http://blog.csdn.net/shiren_Bod/article/details/5766907 下面附上的代码付注释: #include <iostream>using namespace std;int map[3

AcWing算法基础课笔记——高斯消元

高斯消元 用来求解方程组 a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 … a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n a_{11} x_1 + a_{12} x_2 + \dots + a_{1n} x_n = b_1\\ a_

[POJ 3764] The xor-longest Path (Tire树 + 贪心)

POJ - 3674 题意是给你一个树,每条边有一个权值,求得树上一条路径,使路径上每条边权值的异或和最大 首先用一个 DFS把根到任意点的路径的异或和求出来 xorv[i] 由异或的性质可得点 u和点 v的异或和即为 xorv[u]^xorv[v] ( 根到两点 LCA的异或和会消去) 然后问题就转化成在区间内找两个值,使得他们的异或和最大 与 LightOJ - 1269一样的做法,