poj Frequent values 3368

来源:互联网 发布:福州锐捷网络招聘 编辑:程序博客网 时间:2024/06/02 06:14

Frequent values
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 17832 Accepted: 6427

Description

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

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

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

这个题我是被自己感动到了,没想到自己做的第二个RMQ的题可以一次就过,编译也是一次过,太感动了!

哈哈!

题意是:给出一个非降序的整数数组,你的任务是对于一系列询问,回答区间内出现最多的值的次数

说一下如何做

正如《算法竞赛入门经典(训练指南)》198页讲的,

这里我们因为是按非降序排列的,那也就是说相同的数字一定是在一起的

这里我们就用相同的数字为一段来描述

那么说例题中我们就有2 4 1 3分别代表四段

我们用a[]数组来存给出的值,

下面说说我们用到的数组的意义

value[]: 代表第i段的具体数值

coun[]: 代表第i段出现的次数

lef[] : 代表第i段的左端点的位置

righ[]: : 代表第i段的右端点的位置


num[] 数组稍有不同 他指的是第p个位置上为第几段

这样我们只要找num[L]+1, num[R]-1段中的最大值与righ[L]-L+1, R-lef[R]+1,三个中的最大值就可以了,

当然特殊情况也要有考虑

大致可分为三种:


代码如下:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;const int inf = INT_MAX;int value[300005], coun[300005];int num[300005], lef[300005], righ[300005];int a[300005], b[300005][20];int top;void inti(){    a[0] = inf;    top = 0;}void RMQ(){    int i, j;    for ( i = 1;i <= top; i++ )        b[i][0] = coun[i];    for ( j = 1;(1<<j) <= top; j++ )    {        for ( i = 1;i+(1<<(j-1)) <= top; i++ )            b[i][j] = max(b[i][j-1], b[i+(1<<(j-1))][j-1]);    }}int RMQ_check(int y, int x){    int nb = 0;    while ( (1<<nb) <= y-x+1 )        nb++;    return max(b[y-(1<<(nb-1))+1][nb-1], b[x][nb-1]);}int main(){    int i, n, m;    int L, R;    while ( ~scanf ( "%d", &n )&&n != 0 )    {        scanf ( "%d", &m );        inti();        for ( i = 1;i <= n; i++ )        {            scanf ( "%d", &a[i] );            if ( a[i] != a[i-1] )            {                righ[top] = i-1;                top++;                lef[top] = i;                value[top] = a[i];                coun[top] = 0;            }            num[i] = top;            coun[top]++;        }        righ[top] = n;        RMQ();        for ( i = 0;i < m; i++ )        {            scanf ( "%d %d", &L, &R );            if ( num[L] == num[R] )                printf ( "%d\n", R-L+1 );            else if ( num[R]-num[L] == 1 )                printf ( "%d\n", max(righ[num[L]]-L+1, R-lef[num[R]]+1) );            else            {                int ma1 = righ[num[L]]-L+1;                int ma2 =  R-lef[num[R]]+1;                int ma3 = RMQ_check(num[R]-1, num[L]+1);                printf ( "%d\n", max(ma1, max(ma2, ma3)));            }        }    }    return 0;}

代码菜鸟,如有错误,请多包涵!!!

如有帮助记得支持我一下,谢谢!!!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 MP4格式嫌大怎么办 课堂派怎么办改成考试 手机信息幕变黑怎么办 手机百度太耗电怎么办 电脑打不开主页面怎么办? 贴吧被永久封了怎么办 晒课视频太大怎么办 有道精品课过期怎么办 手机缓存变小了怎么办 优学院课程过期怎么办 上公开课紧张怎么办 光纤被老鼠咬断怎么办 石灰粉进入眼睛怎么办 幼儿误吃粉笔怎么办? 吃了粉笔应该怎么办 小孩吃了颜料怎么办 小宝宝吃了纸怎么办 孩子不认真听讲怎么办 监控手机软件离线状态怎么办 云课堂忘记密码怎么办 广州办培训机构怎么办 一师一优课账号忘了怎么办 云相册空间不足怎么办 三星云空间不足怎么办 三星储存空间不足怎么办 宁阳县教育局强制补课怎么办 沉迷网络该怎么办英语 29岁沉迷游戏怎么办 学乐云登录不上怎么办 魔方学院无法识别怎么办 路由器卫士忘记密码怎么办 邮箱号忘记密码怎么办 水卡没钱了怎么办 旅行青蛙换手机怎么办 软件尚未受信任怎么办 百度搜不到的怎么办 百度中搜不到怎么办 山寨云网络异常怎么办 手机太重了怎么办 百度云网页版打不开怎么办 微鲸电视打不开怎么办