Description
l s w lsw lsw 的院子里种了 n n n 朵彼岸花,其中第i朵的彼岸花的美丽值为 a i a_i ai ,彼岸花按照编号从小到大从左向右排成了一排。
现在小 l s w lsw lsw 有 m m m 个问题,他每次会给出一个区间 [ l , r ] [l, r] [l,r] ,他想在编号属于区间 [ l , r ] [l, r] [l,r] 的彼岸花中选出两朵花,使得 a i ⨁ a j a_i ⨁ a_j ai⨁aj (⨁ 表示按位异或操作) 的值最大(如果只能选出一朵花请直接输出 0 0 0 )。
Input
第一行两个整数 n , m ( 1 ≤ n , m ≤ 5 × 1 0 3 ) n, m(1≤n,m≤5×10^3) n,m(1≤n,m≤5×103)。
第二行 n 个整数,分别表示 a 1 , a 2 , … , a n ( 1 ≤ a i ≤ 2 10 ) a_1, a_2, \ldots , a_n (1≤a i ≤ 2^{10} ) a1,a2,…,an(1≤ai≤210)。
接下来 m 行,每行两个整数分别表示一个问题所给出的区间 l , r ( 1 ≤ l ≤ r ≤ n ) l, r(1≤l≤r≤n) l,r(1≤l≤r≤n)。
Output
输出 m m m 行,表示每个问题的答案。
Sample Input
10 10
1 2 3 4 5 6 7 8 9 10
1 2
1 3
1 5
2 6
2 8
2 10
3 7
8 10
6 9
1 7
Sample Output
3
3
7
7
15
15
7
3
15
7
解题思路
不难想这是一道动规题
令 f l , r = f_{l,r}= fl,r= 选 a l a_l al 为其中一个数,在区间 [ l + 1 , r ] [l+1,r] [l+1,r] 里选另外一个数的最大值
则有转移方程 ∑ i = 1 n ∑ j = i + 1 n f i , j = m a x ( f i , j − 1 , a i ⨁ a j ) \sum\limits_{i=1}^n\sum\limits_{j=i+1}^nf_{i,j}=max(f_{i,j-1},a_i ⨁ a_j) i=1∑nj=i+1∑nfi,j=max(fi,j−1,ai⨁aj)
A C c o d e AC \ code AC code
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, m;
int a[maxn];
int f[5005][5005];
signed main()
{
cin >> n >> m;
//build(1,1,n);
for (int i = 1; i <= n; i++)
cin >> a[i];
f[1][1] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
f[i][j] = max(f[i][j - 1], (a[i] ^ a[j]));
}
}
for (int i = 1; i <= m; i++)
{
int l, r;
cin >> l >> r;
if (l > r)
swap(l, r);
if (r - l == 1)
{
cout << f[l][r] << endl;
}
else
{
int ans = 0;
for (int j = l; j <= r; j++)
{
ans = max(ans, f[j][r]);
}
cout << ans << endl;
}
}
}