题目:https://cn.vjudge.net/problem/HDU-5968
思路:
思路一:利用异或运算 a^b^b = a的性质,O(n)预处理出异或的前缀,即可O(1)查询区间连续异或值。之后对于给出的x只需枚举所有子区间即可得到答案。总复杂度O(n + m*n^2)
思路二:直接预处理求出所有区间的异或值和区间长度,将其排序,对于输入的x,二分查找到与x作差绝对值最小的值,其对应的最长区间长度即为答案。
代码:C++
这里只给出思路一的代码
#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <cstring>
#include <set>
#include <stack>
#include <cstdlib>
#include <bitset>
using namespace std;
const int maxn = 100 + 10;
int prexor[maxn];
int a[maxn];
int n;
inline int XOR(int l, int r)
{
return prexor[r] ^ prexor[l-1];
}
int main()
{
int T;
cin >> T;
while(T--)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; i++)
{
prexor[i] = prexor[i-1] ^ a[i];
}
int m;
scanf("%d", &m);
while(m--)
{
int x;
scanf("%d", &x);
int ansval = (int)1e8;
int anslen = 0;
for(int i = 1; i <= n; i++)
{
for(int j = i; j <= n; j++)
{
int t = abs(XOR(i, j) - x);
int len = j - i + 1;
if(t < ansval || (t == ansval && len > anslen))
{
ansval = t;
anslen = len;
}
}
}
cout << anslen << endl;
}
cout << endl;
}
return 0;
}