Frequent values
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 13516   Accepted: 4971

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 10
2 3
1 10
5 10
0

Sample Output

1
4
3

由于是非递减数列。同样的元素必须是连在一块的。能够统计不同元素的个数,以元素的个数建树,给出一段区间,再二分查找出如今第几个元素,特殊考虑最前和最后,中间的用线段树。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=100000+100;
int p;
int tree[maxn<<2];
int num[maxn],sum[maxn];
int a[maxn];
void build(int rt,int l,int r)
{
if(l==r)
{
tree[rt]=num[l];
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
{
return tree[rt];
}
int ans=0;
int mid=(l+r)>>1;
if(L<=mid)
ans=query(rt<<1,l,mid,L,R);
if(R>mid)
ans=max(ans,query(rt<<1|1,mid+1,r,L,R));
return ans;
} int find(int k)
{
int l=1,r=p;
int m;
while (l<=r)
{
m=(l+r)>>1;
if(k>sum[m])
l=m+1;
else if(k<sum[m])
r=m-1;
else
break;
}
if(sum[m-1]>=k)
return m-1;
else if(sum[m]>=k)
return m;
else
return m+1;
}
int main()
{
int n,m;
while(~scanf("%d",&n)&&n)
{
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
memset(tree,0,sizeof(tree));
scanf("%d",&m);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int temp;
temp=0;
p=1;
num[p]=1;
sum[0]=0;
for(int i=1;i<n;i++)
{
if(a[temp]==a[i])
{
num[p]++;
}
else
{
temp=i;
sum[p]=sum[p-1]+num[p];
p++;
num[p]=1;
}
}
sum[p]=sum[p-1]+num[p];
build(1,1,p);
int l,r;
for(int i=0;i<m;i++)
{
int u,v;
int ans=0;
scanf("%d%d",&l,&r);
u=find(l);
v=find(r);
ans=sum[u]-l+1;
if(u==v)
{
printf("%d\n",r-l+1);
continue;
}
if(u+1<=v-1)
ans=max(ans,query(1,1,p,u+1,v-1));
ans=max(ans,r-sum[v-1]);
printf("%d\n",ans);
}
}
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

poj 3368 Frequent values(段树)的更多相关文章

  1. POJ 3368 Frequent values 线段树与RMQ解法

    题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...

  2. POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】

    传送门:http://poj.org/problem?id=3368 Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total S ...

  3. POJ 3368 Frequent values RMQ ST算法/线段树

                                                         Frequent values Time Limit: 2000MS   Memory Lim ...

  4. poj 3368 Frequent values(RMQ)

    /************************************************************ 题目: Frequent values(poj 3368) 链接: http ...

  5. POJ 3368 Frequent values (基础RMQ)

    Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14742   Accepted: 5354 ...

  6. [RMQ] [线段树] POJ 3368 Frequent Values

    一句话,多次查询区间的众数的次数 注意多组数据!!!! RMQ方法: 预处理 i 及其之前相同的数的个数 再倒着预处理出 i 到不是与 a[i] 相等的位置之前的一个位置, 查询时分成相同的一段和不同 ...

  7. POJ 3368 Frequent values(线段树区间合并)

    [题目链接] http://poj.org/problem?id=3368 [题目大意] 有一个有序序列,要求区间查询出现次数最多的数 [题解] 维护每个区间左端点和右端点,以及左右的长度,还有区间的 ...

  8. poj 3368 Frequent values -Sparse-Table

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16537   Accepted: 5981 Description You ...

  9. poj 3368 Frequent values(RMQ)

    题目:http://poj.org/problem?id=3368 题意:给定n个数,顺序为非下降,询问某个区间内的数出现最多的数的 出现次数.. 大白书上的 例题..算是RMQ变形了, 对 原数组重 ...

随机推荐

  1. 如何使用robots不让百度和google收录

    如何使用robots不让百度和google收录   有没有想过,如果我们某个站点不让百度和google收录,那怎么办? 搜索引擎已经和我们达成一个约定,如果我们按约定那样做了,它们就不要收录. 这个写 ...

  2. BZOJ 3402: [Usaco2009 Open]Hide and Seek 捉迷藏

    题目 3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MB Description     贝 ...

  3. ASP.NET Calendar 控件

    ASP.NET Calendar 控件 http://www.w3school.com.cn/aspnet/control_calendar.asp

  4. Median of Two Sorted Arrays-分治法

    题目意思很简单将两个有序数组合并之后的中位数找出来.题目要求使用log(m+n)的时间复杂度来做. 虽然言简意赅,但不得不承认这个题目我自己想了好久也没做出来,隐约觉得应该使用寻找第k大数的算法来做, ...

  5. BZOJ 1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛( dp )

    一道水 dp ...然后我一开始用 BFS ...结果 MLE 了... dp[ i ][ j ][ k ] 由它四个方向上的 k - 1 转移. -------------------------- ...

  6. 一个分组查询 每组前 10 的sql 语句

    USE tmpgo CREATE TABLE Employee( ID int identity(1,1), EmpName varchar(20), EmpSalary varchar(10), E ...

  7. REF CURSOR和CURSOR

    REF CURSOR DECLARE TYPE TY_EMP_CUR IS REF CURSOR; V_Emp_Cur TY_EMP_CUR; V_Id EMP.ID%TYPE; BEGIN OPEN ...

  8. Judge loop in directed graph

    1 深度优先方法 首先需要更改矩阵初始化函数init_graph() 然后我们需要初始化vist标记数组 深度优先访问图,然后根据是否存在back edge判断是否存在环路 算法如下: #includ ...

  9. 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)

    Dijkstra算法 ———————————最后更新时间:2011.9.25———————————Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径. ...

  10. float与position

    使用float会使块级元素的宽高表现为包裹内容(在不设定宽高的情况下)  这是当然的  我们使用float就是使几个div排在一行 当然不可能在宽度上撑满父元素啦  至于高度 不论有没有float 高 ...