当前位置: 代码迷 >> 综合 >> Codeforces483Div1 983B XOR-pyramid
  详细解决方案

Codeforces483Div1 983B XOR-pyramid

热度:86   发布时间:2023-09-27 07:37:43.0

题意:

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


分析:

d(i,j)d(i,j)表示f({ ai,ai+1,,aj})f({ai,ai+1,……,aj})
根据异或的自反性,很容易发现,d(i,j)=d(i+1,j)?d(i,j?1)d(i,j)=d(i+1,j)?d(i,j?1)
根据这个性质,我们就可以在O(n2)O(n2)复杂度内,得到所有子序列的f(b’)
然后再随便搞个O(n2)O(n2)的dp统计区间最大值即可。
dp(i,j)=max{ d(i,j),dp(i+1,j),dp(i,j?1)}dp(i,j)=max{d(i,j),dp(i+1,j),dp(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]);}
}
  相关解决方案