poj 3368 Frequent values(离散化+RMQ)
来源:互联网 发布:java堆内存溢出 编辑:程序博客网 时间:2024/06/16 17:20
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 indicesi and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integersai , ... , aj.
Input
The input consists of several test cases. Each test case starts with a line containing two integersn and q (1 ≤ n, q ≤ 100000). The next line containsn integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for eachi ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The followingq 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
Sample Output
143
题意:给出n个数,非降序排列,有q个询问,对于每个询问a,b,求出区间[a,b]中的出现次数最多的数的出现次数。
思路:先将数据离散化,用x[i]表示原数组,A[i]表示离散化后下标为i的数在原序列的出现次数,s[i]表示离散化后下标为i的数在原数组中第一次出现的位置,in[i]表示i离散化后的下标,然后rmq[i][k]存的是从i开始长度为1<<k的区间的最大A[i]值。对于每个询问(a,b),有三种情况:
(1)若x[a]==x[b],那么这个区间只有一个元素,答案为b-a+1。
(2)若in[x[a]]+1==in[x[b]],即这个区间只有两种元素,答案为两种元素在这个区间出现次数的最大值
(3)若区间的元素种数>2,则先求出首尾两种元素出现次数的最大值,因为中间的元素一定全部落在区间[a,b]上,所以可用RMQ求出中间元素出现次数的最大值。
AC代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <cmath>#include <cstdlib>#define L(rt) (rt<<1)#define R(rt) (rt<<1|1)#define ll long long#define eps 1e-6using namespace std;const int maxn=100005;int A[maxn+20],s[maxn+20],x[maxn+20],in[maxn*2+20],rmq[maxn+20][30];//x[i]表示原数组//A[i]表示离散化后下标为i的数的出现次数//s[i]表示离散化后下标为i的数在原数组中第一次出现的位置//in[i]表示i离散化后的下标//rmq存最大的出现次数int n,m,num;void initRMQ(){ for(int i=1;i<=n;i++) rmq[i][0]=A[i]; for(int k=1;(1<<k)<=n;k++) for(int i=1;i+(1<<k)-1<=n;i++) rmq[i][k]=max(rmq[i][k-1],rmq[i+(1<<(k-1))][k-1]);}int RMQ(int a,int b){ int ia=in[x[a]],ib=in[x[b]]; //ia,ib分别是x[a],x[b]离散化后的下标 if(ia==ib) return b-a+1; //即x[a]==x[b] int sb=s[ib]; //sb分别为x[b]在x数组第一次出现的下标 if(ia+1==ib) return max(sb-1-a+1,b-sb+1); //若[a,b]内只有两种元素 int ans=max(s[ia+1]-1-a+1,b-sb+1); //ans为首尾的最大值 ia++; ib--; int k=(int)(log(ib-ia+1.0)/log(2.0)); ans=max(ans,max(rmq[ia][k],rmq[ib-(1<<k)+1][k])); return ans;}int main(){ int a,b; while(scanf("%d",&num),num) { scanf("%d",&m); n=0;x[0]=0; memset(A,0,sizeof(A)); for(int i=1;i<=num;i++) { scanf("%d",&x[i]); x[i]+=maxn; if(x[i]!=x[i-1]) { in[x[i]]=++n; s[n]=i; } A[n]++; } initRMQ(); while(m--) { scanf("%d%d",&a,&b); printf("%d\n",RMQ(a,b)); } } return 0;}
- poj 3368 Frequent values(离散化+RMQ)
- POJ 3368-Frequent values(RMQ+离散化-最频繁的元素)
- poj 3368 Frequent values(RMQ问题)
- poj 3368(RMQ)Frequent values
- POJ 3368 Frequent values(RMQ)
- poj 3368 Frequent values(RMQ)
- 【POJ 3368】 Frequent values(RMQ)
- POJ - 3368 - Frequent values(RMQ)
- POJ 3368 Frequent values (RMQ)
- poj 3368 Frequent values //RMQ
- POJ 3368 Frequent Values(RMQ)
- [POJ 3368]Frequent values(RMQ)
- Frequent values - POJ 3368 RMQ
- POJ--3368--Frequent values【RMQ】
- POJ 3368 Frequent values (RMQ)
- POJ 3368 Frequent values(RMQ)
- POJ 3368 Frequent values (RMQ)
- POJ 3368 Frequent Values(RMQ)
- 浮点数陷阱
- POJ3608-旋转卡壳
- 杭电1058
- 提交代码到github托管
- CWinAppEx::SetRegistryBase 设置应用程序的默认注册表路径。
- poj 3368 Frequent values(离散化+RMQ)
- CoreAnimation编程指南(六)动画
- ListView点击事件和Listview中的Button点击事件产生冲突
- jsp开发中不支持EL问题
- Eclipse的秘籍
- CoreAnimation编程指南(七)图层Action
- CxImage在使用中delete出错的解决方案
- AfxEnableControlContainer
- 正则表达式语法