Codeforces483Div1 983B XOR-pyramid

题意:

对一个序列b,定义一种运算
f ( b ) = { b [ 1 ] if  m = 1 f ( b [ 1 ] b [ 2 ] , b [ 2 ] b [ 3 ] , , b [ m 1 ] b [ m ] ) otherwise,
表示异或)
现在给出一个长为N的序列b,以及q次询问,每次询问给出 l , r 表示从l到r这段子序列中,最大的f(b’)的值
N 5000 , q 100000


分析:

d ( i , j ) 表示 f ( { a i , a i + 1 , , a j } )
根据异或的自反性,很容易发现, d ( i , j ) = d ( i + 1 , j ) d ( i , j 1 )
根据这个性质,我们就可以在 O ( n 2 ) 复杂度内,得到所有子序列的f(b’)
然后再随便搞个 O ( n 2 ) 的dp统计区间最大值即可。
d p ( i , j ) = m a x { d ( i , j ) , d p ( i + 1 , j ) , d p ( i , j 1 ) }
每次询问直接输出答案即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 5010
using namespace std;
typedef long long ll;
int n;
ll a[MAXN];
ll dp[MAXN][MAXN],ans[MAXN][MAXN];
int main(){
    SF("%d",&n);
    for(int i=1;i<=n;i++){
        SF("%I64d",&a[i]); 
        dp[i][i]=a[i];
        ans[i][i]=a[i];
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j+i<=n;j++){
            dp[j][i+j]=dp[j][i+j-1]^dp[j+1][i+j];
            ans[j][i+j]=dp[j][i+j];
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j+i<=n;j++){
            ans[j][i+j]=max(ans[j][i+j],max(ans[j+1][i+j],ans[j][i+j-1]));
        }
    int q,l,r;
    SF("%d",&q);
    for(int i=1;i<=q;i++){
        SF("%d%d",&l,&r);
        PF("%I64d\n",ans[l][r]);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/80461206
今日推荐