UVA - 11235 Frequent values

来源:互联网 发布:程序员简历范文 编辑:程序博客网 时间:2024/05/16 19:49
Frequent values
Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

Submit Status

Description

Download as PDF
2007/2008 ACM International Collegiate Programming Contest 
University of Ulm Local Contest

Problem F: Frequent values

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

Input Specification

The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j(1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the query.

The last test case is followed by a line containing a single 0.

Output Specification

For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.

Sample Input

10 3-1 -1 1 1 1 1 3 10 10 102 31 105 100

Sample Output

143

A naive algorithm may not run in time!



分析:
树状数组RMQ问题。除了树状数组外,还涉及到了游程编码,初学还是比较难的。
还是没有完全理解,特点是自己敲代码的话,没把握ac。以后继续看。
ac代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
int a[maxn],d[maxn][20];//a多余?
int n,q;
int size;
//int value[maxn],count0[maxn]={0};
int num[maxn],left0[maxn],right0[maxn];


void RLE()//游程编码,维护a,num,left0,right0四个数组.好好体会
{
    int x,cnt=-1,l;
    int maxnum=0xffffffff;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        if(x==maxnum)
        {
            a[cnt]++;
            num[i]=cnt;
            left0[i]=l;
        }
        else
        {
            if(cnt>=0)
            {
                for(int j=l;j<=i-1;j++)
                    right0[j]=i-1;
            }
            cnt++;
            l=i;
            num[i]=cnt;
            left0[i]=l;
            a[cnt]=1;
            maxnum=x;
        }
    }
    for (int i = l; i < n; i++)
        right0[i] = n-1;
    size = cnt + 1;
}


void RMQ_init()
{
    int n=size;//优化,缩小范围
    for(int i=0;i<n;i++)
    d[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++)
    for(int i=0;i+(1<<j)-1<n;i++)
    d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}


int RMQ(int L,int R)
{
    if(L>R) return 0;//这句话的作用?
    int k=0;
    while((1<<(k+1))<=R-L+1)
    k++;
    return max(d[L][k],d[R-(1<<k)+1][k]);
}


int main()
{
    while(scanf("%d%d",&n,&q)&&n)
    {
        RLE();
        RMQ_init();
        while(q--)
        {
            int L,R;
            scanf("%d%d",&L,&R);
            L--;R--;//使得从0开始
            if(num[L]==num[R])//
            printf("%d\n",R-L+1);//多余
            else
            {
                int t1=right0[L]-L+1;
                int t2=R-left0[R]+1;
                int t3=RMQ(num[L]+1,num[R]-1);
                int ans=max(t1,max(t2,t3));
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}
0 0
原创粉丝点击