• uva11235


    N - Frequent values

    题意:给出一个非递减数组,求【L,R】区间内出现最多的数的次数。

    分析:看训练指南吧。

    代码:

    #include <map>
    #include <queue>
    #include <vector>
    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define cls(x) memset(x,0,sizeof(x))
    #define clslow(x) memset(x,-1,sizeof(x))
    
    const int maxlog=20;
    const int maxn=1e5+100;
    
    int n,m;
    
    int a[maxn];
    int cnt[maxn],num[maxn],Left[maxn],Right[maxn];
    
    struct RMQ {
        int d[maxn][maxlog];
        void init(int* a,int n)
        {
            for(int i=1;i<=n;i++)    d[i][0]=a[i];
            for(int j=1;(1<<j)<=n;j++){
                for(int i=1;i+(1<<j)<=n;i++){
                    d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
                }
            }
        }
        int query(int L,int R)
        {
            int k=0;
            while((1<<(k+1))<=R-L+1)    k++;
            return max(d[L][k],d[R-(1<<k)+1][k]);
        }
    };
    RMQ rmq;
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        while(scanf("%d",&n)!=EOF&&n)
        {
            scanf("%d",&m);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
    
            int tot=1,start;
            for(int i=1;i<=n+1;i++){
                if(i==1||a[i]!=a[i-1]){
                    if(i>1){
                        cnt[tot]=i-start;
                        for(int j=start;j<i;j++){
                            num[j]=tot;
                            Left[j]=start;
                            Right[j]=i-1;
                        }
                        tot++;
                    }
                    start=i;
                }
            }
            rmq.init(cnt,tot-1);
    
            for(int i=1;i<=m;i++){
                int l,r,ans;
                scanf("%d%d",&l,&r);
                if(num[l]==num[r]){
                    ans=r-l+1;
                }
                else{
                    ans=max(Right[l]-l+1,r-Left[r]+1);
                    if(num[l]+1<num[r]) ans=max(ans,rmq.query(num[l]+1,num[r]-1));
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2019 Multi-University Training Contest 3
    SDU暑期集训排位(2)
    2019牛客暑期多校训练营(第四场)
    2019牛客暑期多校训练营(第三场)
    2019 Multi-University Training Contest 2
    2019 Multi-University Training Contest 1
    hdu1158 Employment Planning(dp)
    hdu 1130How Many Trees?(卡特兰数)
    C++大整数类模板
    组合数模板
  • 原文地址:https://www.cnblogs.com/shutdown113/p/9346623.html
Copyright © 2020-2023  润新知