Codeforces Round #483 (Div. 2) D. XOR-pyramid(dp)
题意:
定义一个函数f(b),b对应一个数组,作用方式见题意。给你一个长度为n的序列b,然后给你q次询问,对于每次询问,给你l r,问你在[l,r]这段区间内所有子串中f的最大值为多少。
解析:定义f[l][r]为在[l,r]这个区间内函数f的结果,那么有:
当l=r时f[l][r]=b[l]
否则 f[l][r]=f[l][r−1]⊕f[l+1][r]
所以我们可以按长度枚举
求出f[l][r]并更新ans[l][r]
影响ans[l][r]的值三个
f[l][r] 和ans[l][r-1]以及ans[l+1][r];(也就是当前长度-1的子区间)
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define pll pair<ll,ll>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
#define rson rt<<1|1,m+1,r
#define lson rt<<1,l,m
using namespace std;
const int N=5e3+100;
ll ans[N][N];
ll f[N][N];
int main()
{
#ifdef LOCAL_DEFINE
freopen("D:\\rush.txt","r",stdin);
#endif
ios::sync_with_stdio(false),cin.tie(0);
ll n,q,l,r;
cin>>n;
rep(i,1,n)
cin>>f[i][i],ans[i][i]=f[i][i];
for (int len = 2; len <= n; len++)
for (l = 1, r; (r = l + len - 1) <= n; l++)
{
f[l][r] = f[l][r-1] ^ f[l+1][r];
ans[l][r] = max(f[l][r],max(ans[l][r-1], ans[l+1][r]));
}
cin>>q;
while(q--)
{
cin>>l>>r;
cout<<ans[l][r]<<endl;
}
return 0;
}