zoukankan      html  css  js  c++  java
  • Frequent values[RMQ]

    题目:

     题意:给一个长度为n的非降序的数组,询问q次,问[L,R]内出现最多的数字的出现次数。

     思路:因为数组是非降序的,相同的数字会聚集到一起,可以进行离散化,用cnt[i]表示第i段数字一共出现的次数,num[p]表示 p位置的编号,lft[p]表示p位置的数字的最左位置,rit[p]同理。那么对于每个查询[L,R],最大值应该是三个部分:L到rit[L],lft[R]到R,以及从rit[L]+1到lft[R]-1中的最大值。这是一个不需要修改的区间最值查询,用ST可做。

     1 #include<bits/stdc++.h>
     2 #define fi first
     3 #define se second
     4 #define pb(i) push_back(i)
     5 #define rep(i,a,b) for(int i=a;i<=b;i++)
     6 #define per(i,a,b) for(int i=b;i>=a;i--)
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define VI vector<int>
     9 #define VLL vector<ll>
    10 #define MPII map<pair<int,int>,int>
    11 #define mp make_pair
    12 #define PQI priority_queue<int>
    13 using namespace std;
    14 typedef long long ll;
    15 typedef unsigned long long ull;
    16 const int N = 1e6+10;
    17 const int INF = 0x3f3f3f3f;
    18 const int inf = - INF;
    19 const int mod = 1e9+7;
    20 const double pi = acos(-1.0);
    21 const double eps=1e-5;
    22 int n,pos=0;
    23 int value[N],cnt[N];
    24 int num[N];
    25 int lft[N],rit[N];
    26 int d[N][30];
    27 void RMQ_init(){
    28     memset(d,0,sizeof(d));
    29     for(int i=0;i<=pos;i++) d[i][0]=cnt[i];
    30     for(int j=1;(1<<j)<=pos;j++){
    31         for(int i=1;i+(1<<j)-1<=pos;i++)
    32             d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    33     }
    34 }
    35 int RMQ(int l,int r){
    36     int ans=0;
    37     if(num[l]==num[r]) return r-l+1;
    38     ans=max(ans,max(rit[l]-l+1,r-lft[r]+1));
    39     int k=0;
    40     int L=rit[l]+1,R=lft[r]-1;
    41     if(num[L]>num[R]) return ans;//中间没有其他数字
    42     if(num[L]==num[R]) return max(ans,R-L+1);
    43     while(1<<(k+1)<=num[R]-num[L]+1) k++;
    44     return max(ans,max(d[num[L]][k],d[num[R]-(1<<k)+1][k]));
    45 }
    46 //vector<int>a;
    47 int a[N];
    48 int main(){
    49     int q;
    50     while(scanf("%d",&n)==1&&n){
    51         scanf("%d",&q);
    52         pos=0;
    53         memset(num,0,sizeof(num));
    54         memset(value,0,sizeof(value));
    55         memset(lft,0,sizeof(lft));
    56         memset(rit,0,sizeof(rit));
    57         memset(cnt,0,sizeof(cnt));
    58         a[0]=inf;
    59         for(int i=1;i<=n;i++){
    60             scanf("%d",&a[i]);
    61             if(a[i]!=a[i-1]){
    62                 value[++pos]=a[i];
    63                 cnt[pos]++;
    64                 lft[i]=i;
    65             }
    66             else{
    67                 cnt[pos]++;
    68                 lft[i]=lft[i-1];
    69             }
    70             num[i]=pos;
    71         }
    72         for(int i=1;i<=n;i++)
    73             rit[i]=lft[i]+cnt[num[i]]-1;
    74         RMQ_init();
    75         while(q--){
    76             int l,r;
    77             scanf("%d%d",&l,&r);
    78             printf("%d
    ",RMQ(l,r));
    79         }
    80     }
    81     system("pause");
    82     return 0;
    83 }
  • 相关阅读:
    hdu 2553 N皇后问题(dfs)
    hdu 1043 Eight(双向bfs)
    牛人的ACM经验 (转)
    康托和逆康托展开(转)
    hiho Mission Impossible 6(模拟 未提交验证。。)
    数组越界也可以这么巧~~~
    poj 1679 The Unique MST(次小生成树)
    zoj 3204 Connect them(最小生成树)
    hdu 4463 Outlets(最小生成树)
    廖雪峰Java1-2程序基础-8字符和字符串
  • 原文地址:https://www.cnblogs.com/yoshinaripb/p/13881097.html
Copyright © 2011-2022 走看看