Codeforces483Div1 983B XOR-pyramid

题意:

对一个序列b,定义一种运算
f(b)={b[1]f(b[1]b[2],b[2]b[3],,b[m1]b[m])if m=1otherwise, 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 表示从l到r这段子序列中,最大的f(b’)的值
N5000,q100000 N ≤ 5000 , q ≤ 100000


分析:

d(i,j) d ( i , j ) 表示 f({ai,ai+1,,aj}) f ( { a i , a i + 1 , … … , a j } )
根据异或的自反性,很容易发现, d(i,j)=d(i+1,j)d(i,j1) d ( i , j ) = d ( i + 1 , j ) ⊕ d ( i , j − 1 )
根据这个性质,我们就可以在 O(n2) O ( n 2 ) 复杂度内,得到所有子序列的f(b’)
然后再随便搞个 O(n2) O ( n 2 ) 的dp统计区间最大值即可。
dp(i,j)=max{d(i,j),dp(i+1,j),dp(i,j1)} 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]);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值