题目链接:http://codeforces.com/contest/984/problem/D
题意:给你一个计算区间f函数的公式,举例f(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 然后现在给你一个数列,n<=5000,然后q个询问,q<=100000,每次询问lr区间内f函数的最大值是多少
分析:首先一共有5000个数,那么有效区间就是5000*5000个,然后我们可以直接求出每一个区间的f值,其实就是一棵树,每一个结点的最大值等于所有子节点的最大值,然后我们只需要再维护好每个结点的最大值,时间复杂度n²,然后询问的时候O(1)回答就可以了。
其实你只需要把n个数写下来 然后再求区间间隔为2的f值,求区间间隔为3的f值,就会得到一个递推,即dp[i][j]=dp[i-1][j]^dp[i-1][j+1]。然后你再顺着这个递推走一遍,维护成最大值就可以了。查询的时候输出dp[l-r+1][l]就可以了。
AC代码:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 long long a[5005]; 7 long long b[5005][5005]; 8 int n,q; 9 int l,r; 10 long long query(int x,int y){ 11 12 } 13 int main(){ 14 ios_base::sync_with_stdio(false); 15 cin.tie(0); 16 17 cin>>n; 18 for(int i=1;i<=n;i++){ 19 cin>>a[i]; 20 b[1][i]=a[i]; 21 } 22 for(int i=2;i<=n;i++){ 23 for(int j=1;j<=n-i+1;j++){ 24 b[i][j]=b[i-1][j]^b[i-1][j+1]; 25 } 26 } 27 for(int i=2;i<=n;i++){ 28 int d=n-i+1; 29 for(int j=1;j<=d;j++){ 30 long long pp=max(b[i-1][j],b[i-1][j+1]); 31 b[i][j]=max(b[i][j],pp); 32 } 33 } 34 cin>>q; 35 for(int i=1;i<=q;i++){ 36 cin>>l>>r; 37 cout<<b[r-l+1][l]<<endl; 38 } 39 40 return 0; 41 }