[线性基]Link is as bear 2022杭电多校第4场 1011

Link, a famous bear magician in Bear Institute of Talented(BIT), has recently learned new magic.

That is, given a array aa containing nn elements a_{1},...,a_{n}a1​,...,an​, and Link can cast the following magic:

Link can choose two integers l,rl,r such that 1\leq l \leq r \leq n1≤l≤r≤n, making all a_{i}=xor(l,r)ai​=xor(l,r) where l\leq i\leq rl≤i≤r and xor(l,r)xor(l,r) denotes the bitwise-xor(\oplus⊕) of all elements in [l,r][l,r]. More formally, xor(l,r)=a_l\oplus a_{l+1}\oplus ... \oplus a_rxor(l,r)=al​⊕al+1​⊕...⊕ar​.

Link can cast this magic any time(possibly, zero) and can choose l,rl,r arbitrarily. However, since Link has a sort of Obsessive-Compulsive Disorder(OCD), he wants all elements to become the same after his operation. Now, he wonders about the maximum of this same value.

What's more, Link finds that the given array has a weird property: there always exists at least one pair of x,y(x\neq y)x,y(x=y) such that a_x= a_yax​=ay​.

Input

The first line contains an integer T(1\leq T \leq 3*10^4)T(1≤T≤3∗104), the number of the test cases.

The first line of each test case is an interger n(1\leq n\leq 10^5)n(1≤n≤105), the length of the array aa.

The second line of each test case containing nn integers, while the ii-th denoting a_i(0\leq a_i \leq 10^{15})ai​(0≤ai​≤1015). It's guaranteed that there always exists at least one pair of x,y(x\neq y)x,y(x=y) such that a_x= a_yax​=ay​.

It's also guaranteed that \Sigma n \leq 10^6Σn≤106.

Output

For each test case, output a single intergers indicating the maximum of the same value after Link's operations.

Sample

InputOutput
 
2 
5 
10 10 10 10 10 
4 
1 1 2 1
 
10 
3

题意: 给出n个数字,你可以无限制释放法术,每次法术可以将一段区间内的值更改为它们的异或值,例如某次法术给出l和r,那么就会把a[l], a[l+1], ......, a[r-1], a[r]全部更改为a[l] xor a[l+1] xor ...... xor a[r-1] xor a[r],并且已知初始时总存在两个不同位置的值相同,现在要通过施放法术将这些数字变成相同的数字,并且它们的值要尽可能大,输出最大可能值。

分析: 由于异或同一个数字偶数次等价于没进行异或,所以不管过程中如何异或,最终答案一定是来自某些数字的异或值。但是任意数字的异或值一定能覆盖整个数组吗?实际上是可以的,证明也比较简单,以两个任意数字的异或值为例,一开始数组元素为1 2 5 3 1 4 2,假如任取的两数字为5和4,现在目标是让5 xor 4的结果也就是1填满整个数组,施展法术的用下图中的绿框表示,首先对5旁边任意两数字施法,这样这两数字会变成值相同的元素,并不关心它们的具体数值是多少,之后再对5和这两元素一起施法,那么现在就有了三个5,按照这种方式不断让5这段数字扩展直到遇到4,此时可以让5和4异或,那就得到了两个我们需要的最终结果了,再按照上面那种扩展方式就可以用结果填满整个数组了。

其实任意三个数字的异或值或者三个以上的异或值也可以用这种方法填满整个数组,只不过填三个或以上数字的异或值有可能要借助那两个相同的数字,否则没法填满数组(具体是哪种情况可以自己多模拟模拟),也就是将那两个相同的数字也作为要参与异或的数字,然后按照上面说的方式向两侧扩展,由于两数异或起来是0,所以对结果不产生影响,这样就证明完了。

由于任意数字的异或值都可以通过施展若干次法术铺满数组,所以它们都是合法的结果,只需要取其中的最大值作为答案即可,也就是说答案为任意数字异或值的最大值,这个值可以通过线性基得到。

具体代码如下:

#include <bits/stdc++.h>
#define int long long
using namespace std;

typedef long long LL;

struct Linear_Basis{
    LL b[63],nb[63],tot;
    void init(){
        tot=0;
        memset(b,0,sizeof(b));
        memset(nb,0,sizeof(nb));
    }
    bool ins(LL x){
        for(int i=62;i>=0;i--)
            if (x&(1LL<<i)){
                if (!b[i]) {b[i]=x;break;}
                x^=b[i];
            }
        return x>0;
    }
    LL Max(){
        LL res=0;
        for(int i=62;i>=0;i--)
            res=max(res,res^b[i]);
        return res;
    }
    LL Min(){
        for(int i=0; i<=62; i++)
        if(b[i]!=0) return b[i];
    }
    void rebuild(){
        for(int i=62;i>=0;i--)
            for(int j=i-1;j>=0;j--)
                if (b[i]&(1LL<<j)) b[i]^=b[j];
        for(int i=0;i<=62;i++)
            if (b[i]) nb[tot++]=b[i];
    }
    LL Kth_Max(LL k){
        LL res=0;
        for(int i=62;i>=0;i--)
            if (k&(1LL<<i)) res^=nb[i];
        return res;
    }
};

signed main(){
	int T;
	cin >> T;
	while(T--){
		int n;
		scanf("%lld", &n);
		Linear_Basis LB;
		LB.init(); 
		for(int i = 1; i <= n; i++){
			int t;
			scanf("%lld", &t);
			LB.ins(t);
		}
		printf("%lld\n", LB.Max());
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值