zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    也谈一下关于兔子的问题
    关于sql函数返回表
    关于1000瓶水的问题
    WWF的疑问
    天干和地支
    在若干个整数中找到相加之和为某个整数的所有组合的算法
    输出一个数组的全排列
    新的博客, 新的里程
    学习搜索引擎心得(10.2511.25)
    下一个阶段(用C++重写Lucene的计划)
  • 原文地址:https://www.cnblogs.com/shutdown113/p/9346623.html
Copyright © 2011-2022 走看看