优美值

    •                                                                                                   优美值
    • 题目描述
      • 一个长度为n的序列,对于每个位置i 的数ai都有一个优美值,其定义是:找到序列中最长的一段[l,r],满足l<=i<=r ,且[l,r]中位数为ai(我们比较序列中两个位置的数的大小时, 以数值为第一关键字,下标为第二关键字比较。这样的话[l,r]的长度只有可能是奇数),r-l+1就是i的优美值
      • 接下来有 Q个询问,每个询问[l,r]表示查询区间[l,r]内优美值的最大值

   输入格式

  • 第一行输入n接下来n个整数,代表 ai
  • 接下来一行为整数Q,代表有 Q个区间需要查询。
  • 接下来Q行,每行 两个整数l,r(l<=r),表示区间的左右端点。

输出格式

对于每个区间的询问,输出答案。

样例

样例输入

8
16 19 7 8 9 11 20 16
8
3 8
1 4
2 3
1 1
5 5
1 2
2 8
7 8

样例输出

7
3
1
3
5
3
7
3

数据范围与提示

n<=2000,Q<=100000,ai<=200
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=2000+10;
 6 int a[maxn],w[maxn];
 7 int n,l[maxn<<1],r[maxn<<1];
 8 void solve(){
 9      int cnt=0;
10      for(int i=1;i<=n;i++){
11         memset(l,0,sizeof(l));
12         memset(r,0,sizeof(r));
13         l[n]=i;
14         r[n]=i;
15         cnt=0;
16         for(int j=i-1;j>=1;j--){
17            if(a[j]>a[i]) cnt++;
18            else cnt--;
19            l[cnt+n]=j;
20         }   
21         cnt=0;
22         for(int j=i+1;j<=n;j++){
23            if(a[j]>=a[i]) cnt++;
24            else cnt--;
25            r[cnt+n]=j;
26         }
27         int t=max(i-1,n-i);
28         for(int j=1-i;j<=i-1;j++){
29            if(l[j+n]>0&&r[-j+n]>0){
30               w[i]=max(w[i],r[n-j]-l[j+n]+1);
31            }
32         }
33      }
34 }
35 int main(){
36     scanf("%d",&n);
37     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
38     solve();
39     int q;
40     scanf("%d",&q);
41     for(int i=1;i<=q;i++){
42        int x,y;
43        scanf("%d%d",&x,&y);
44        int ans=0;
45        for(int j=x;j<=y;j++){
46            ans=max(ans,w[j]);
47        }
48        printf("%d\n",ans);
49     }
50     return 0;
51 }
View Code

 

posted @ 2020-07-10 17:43  ddoodd  阅读(193)  评论(0编辑  收藏  举报