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;
}
posted @ 2018-05-16 13:11  ffgcc  阅读(71)  评论(0编辑  收藏  举报