codeforces 984 D. XOR-pyramid

题目链接:http://codeforces.com/contest/984/problem/D

题意:给你一个计算区间f函数的公式,举例f(1,2,4,8)=f(12,24,48)=f(3,6,12)=f(36,612)=f(5,10)=f(510)=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 }
View Code

 

posted @ 2018-05-18 14:27  BadboyQAQ  阅读(178)  评论(0编辑  收藏  举报