CodeForces - 983B XOR-pyramid(两次区间DP/记忆化DFS)

B. XOR-pyramid
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

For an array bb of length mm we define the function ff as

f(b)={b[1]if m=1f(b[1]b[2],b[2]b[3],,b[m1]b[m])otherwise,f(b)={b[1]if m=1f(b[1]⊕b[2],b[2]⊕b[3],…,b[m−1]⊕b[m])otherwise,

where  is bitwise exclusive OR.

For example, f(1,2,4,8)=f(12,24,48)=f(3,6,12)=f(36,612)=f(5,10)=f(510)=f(15)=15f(1,2,4,8)=f(1⊕2,2⊕4,4⊕8)=f(3,6,12)=f(3⊕6,6⊕12)=f(5,10)=f(5⊕10)=f(15)=15

You are given an array aa and a few queries. Each query is represented as two integers ll and rr. The answer is the maximum value of ff on all continuous subsegments of the array al,al+1,,aral,al+1,…,ar.

Input

The first line contains a single integer nn (1n50001≤n≤5000) — the length of aa.

The second line contains nn integers a1,a2,,ana1,a2,…,an (0ai23010≤ai≤230−1) — the elements of the array.

The third line contains a single integer qq (1q1000001≤q≤100000) — the number of queries.

Each of the next qq lines contains a query represented as two integers llrr (1lrn1≤l≤r≤n).

Output

Print qq lines — the answers for the queries.

Examples
input
Copy
3
8 4 1
2
2 3
1 2
output
Copy
5
12
input
Copy
6
1 2 4 8 16 32
4
1 6
2 5
3 4
1 2
output
Copy
60
30
12
3
Note

In first sample in both queries the maximum value of the function is reached on the subsegment that is equal to the whole segment.

In second sample, optimal segment for first query are [3,6][3,6], for second query — [2,5][2,5], for third — [3,4][3,4], for fourth — [1,2][1,2].


题意:定义一个异或和f(),f(a)=a,f(a,b)=a^b,f(a,b,c)=f(a^b,b^c)这样子。

然后Q次查询(q<=100000),每次查询区间[l,r]中最大的f()值。区间长度n<=5000。

思路:区间DP。刚开始还真是没往这方面想,但是在纸上推了一下发现dp[l][r](区间[l,r]中的所有数的f())就等于dp[l+1][r]^dp[l][r-1](l<r),然后dp[l][r]=a[l](l==r)   之后用dfs写了一发WA,思路是对的,后来发现就是区间DP,先求出区间[l,r]的f()值,再从小到大枚举区间长度,统计区间最大值即可。(于是代码写起来就比较随意了,分为两部分,一部分求求出区间[l,r]的f()值,一部分统计区间最大值,任意一部分都可以直接用两重for循环或者记忆化dfs完成状态转移

比赛的时候我没想到区间dp,用的记忆化dfs(原理一样)。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=5010;
int n,m,k,f,flag;
int ans,tmp,cnt,dp[maxn][maxn];
int a[maxn][maxn],c[maxn];
char s[maxn];
int dfs(int l,int r)
{
    if(dp[l][r]!=-1) return dp[l][r];
    ans=dfs(l+1,r)^dfs(l,r-1);
    dp[l][r]=ans;
    return ans;
}
int dfs2(int l,int r)
{
    if(a[l][r]!=-1) return a[l][r];
    a[l][r]=max(dp[l][r],dfs2(l+1,r)); //这次需要注意如何统计最大值,刚开始写了WA
    a[l][r]=max(a[l][r],dfs2(l,r-1));
    return a[l][r];
}
int main()
{
    int T,cas=1;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,-1,sizeof(dp));
        memset(a,-1,sizeof(a));
        ans=0;    flag=1;
        k=1;
        for(int i=1;i<=n;i++) {scanf("%d",&c[i]);
         dp[i][i]=a[i][i]=c[i];
         }
         dfs(1,n);
         dfs2(1,n);
        scanf("%d",&k);
        while(k--)
        {
        int x,y;
        scanf("%d %d",&x,&y);
        printf("%d\n",a[x][y]);
        }
        //if(flag) puts("Yes");else puts("No");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/lsd20164388/article/details/80604793