zoukankan      html  css  js  c++  java
  • POJ 3368 (ST表)

    链接:http://poj.org/problem?id=3368

    题意:给出n个连续单调不递减数,q次询问,每次询问区间(L,R)出现频率最多的数,问出现了多少次

    思路:因为n个数是单调不递减的,所以可以预处理一个频率数组cnt[ ],cnt[ i ]记录某个数到 i 位置时,出现了多少次,再预处理一个index数字,记录每一段相同的数字,最右端的位置,因为每次询问的时候可能会出现一部分连续的数被L这个位置隔开,cnt[i]只记录了某个数到i位置出现了多少次,被隔开的部分多算了,所以需要减去,每次询问(L,R)的时候分为两个部分,前一部分查询出 index[ L ] - l为被隔开的部分,后一部分用st表维护区间最值求即可。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<queue> 
     7 using namespace std;
     8 const int maxn = 100005;
     9 int n,q;
    10 int a[maxn];
    11 int cnt[maxn];
    12 int index[maxn];
    13 int Log[maxn];
    14 int f[maxn][21];
    15 void pre(){
    16     Log[1] = 0;
    17     Log[2] = 1;
    18     for(int i =3;i<maxn;i++) Log[i] = Log[i/2] + 1; 
    19 }
    20 void st(){
    21     for(int i = 1;i<=n;i++){
    22         f[i][0] = cnt[i]; 
    23     }
    24     for(int j = 1;j<=Log[n+1];j++){
    25         for(int i = 1;i+(1<<j)-1<=n;i++){
    26             f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    27         }
    28     }
    29 }
    30 int main(){
    31     pre();
    32     while(~scanf("%d",&n)){
    33     if(n == 0) break;
    34     scanf("%d",&q);
    35     for(int i = 1;i<=n;i++){
    36         scanf("%d",&a[i]);
    37         if(i == 1) cnt[i] = 1;
    38         if(a[i]!=a[i-1]) cnt[i] = 1;
    39         else cnt[i] = cnt[i-1] + 1;
    40     }
    41     st();
    42     for(int i = n;i>=1;i--){
    43         if(a[i] == a[i+1]) index[i] = index[i+1];
    44         else index[i] = i;
    45     }
    46     while(q--){
    47         int l,r;
    48         int ans = 0;
    49         scanf("%d%d",&l,&r);
    50         if(index[l] == index[r]){
    51             ans = r - l + 1;
    52         }
    53         else if(index[l] == index[l-1]){//判断一下,如果在l左边的数和l位置的数相等,就说明被隔开了 
    54             int t = min(index[l],r)+1;//算出后一部分区间的左端点 
    55             int ans1 = t - l ;//ans1单独计算 算出被隔开了多少数,这一部分单独计算 
    56             int s = Log[r-t+1];//剩下部分用st表求 
    57             ans = max(ans1,max(f[t][s],f[r-(1<<s)+1][s]));//两者取最大值 
    58         }
    59         else{
    60             int s = Log[r-l+1];
    61             ans = max(f[l][s],f[r-(1<<s)+1][s]);
    62         }
    63         printf("%d
    ",ans);
    64     }
    65   }
    66     return 0;
    67 }
  • 相关阅读:
    20171104 DOI Excel 导出
    ABAP 字符串处理
    SE80 开发对象
    ABAP开发中message dump
    物料单位转换的两个函数
    ABAP 多行消息分别显示弹窗
    隐藏你写的程序代码
    学习笔记:Javascript 变量 包装对象
    访问平安银行网站时出现证书问题 NET::ERR_CERT_SYMANTEC_LEGACY
    关于跨域问题
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12199409.html
Copyright © 2011-2022 走看看