Frequent values(线段树+离散化)
来源:互联网 发布:node v6.2.2 x64.msi 编辑:程序博客网 时间:2024/06/11 01:26
Frequent values
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 22 Accepted Submission(s) : 9
Problem 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
<p>The input consists of several test cases. Each test case starts with a line containing two integers <strong>n</strong> and <strong>q</strong> (<i>1 ≤ n, q ≤ 100000</i>). The next line contains <strong>n</strong> integers <strong>a<sub>1</sub> , ... , a<sub>n</sub></strong> (<i>-100000 ≤ a<sub>i</sub> ≤ 100000</i>, for each <i>i ∈ {1, ..., n}</i>) separated by spaces. You can assume that for each <i>i ∈ {1, ..., n-1}: a<sub>i</sub> ≤ a<sub>i+1</sub></i>. The following <strong>q</strong> lines contain one query each, consisting of two integers <strong>i</strong> and <strong>j</strong> (<i>1 ≤ i ≤ j ≤ n</i>), which indicate the boundary indices for the <br>query.</p><p>The last test case is followed by a line containing a single <i>0</i>.</p>
Output
<p>For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.</p>
Sample Input
10 3-1 -1 1 1 1 1 3 10 10 102 31 105 100
Sample Output
143
Source
PKU
Statistic | Submit | Back
题意
给一个长度为N的序列,求l~r之间出现最多的数字出现的次数
思路:
先将数据 进行离散化,然后用一个数组记录每个位置的离散之后得数·,因为题目要求是非递减的,所以这给题目解决提供很大的方便,然后就是用线段树求某个离散数所包括的区间范围内的最大的出现个数。离散化的优点就是线段树数组的大小可以开的很小。看代码吧:
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define L(rt) (rt<<1)#define R(rt) (rt<<1|1)const int maxn=100005;int n;int a[maxn],b[maxn];//b记录每个离散得到的点对应区间的端点int ans;struct node{int start,end;}ss[maxn];struct Tree{int l,r;int maxx;}tree[maxn<<2];void build(int l,int r,int pos){ //建树注意最大值的求法 tree[pos].l=l; tree[pos].r=r; if(l==r){ tree[pos].maxx=ss[l].end-ss[l].start+1;return;} int mid=(l+r)>>1; build(l,mid,L(pos)); build(mid+1,r,R(pos)); tree[pos].maxx=max(tree[L(pos)].maxx,tree[R(pos)].maxx);}//区间求最值,套模板即可int query(int l,int r,int pos){if(tree[pos].l==l&&tree[pos].r==r)return tree[pos].maxx;else{int mid=(tree[pos].l+tree[pos].r)>>1;if(r<=mid)return query(l,r,L(pos));else if(l>mid)return query(l,r,R(pos));else return max(query(l,mid,L(pos)),query(mid+1,r,R(pos)));}}int main(){// ios::sync_with_stdio(false);int q;int pre;int i,j;while(~scanf("%d",&n)){if(n==0)break;scanf("%d",&q);for(i=1;i<=n;i++)scanf("%d",&a[i]);pre=100001;ans=0;//ans是记录离散化后形成的数的个数for(i=1;i<=n;i++){if(a[i]!=pre){pre=a[i];ans++;ss[ans].start=i;ss[ans].end=i;}elsess[ans].end=i;b[i]=ans;//标记原序列中每个下标对应离散后的点}build(1,ans,1);while(q--){int x,y,xx,yy;scanf("%d%d",&x,&y);if(x==y){printf("1\n");continue;}xx=b[x],yy=b[y];//下标为x和y的点离散后对应的点 if(xx==yy){ //位于同一个离散数的区间内,离散后的点是用一个点,说明[x,y]为同一个点集 printf("%d\n",y-x+1);continue;}else{//求三部分以上的情况,不是同一个点集,就分为三部分,第二部分的点集最大值用线段树来求int ans1=ss[xx].end-x+1;int ans2=y-ss[yy].start+1;int ans3=0;if(yy>xx+1)ans3=query(xx+1,yy-1,1); printf("%d\n",max(max(ans1,ans2),ans3));continue;}}} return 0;}
阅读全文
0 0
- Frequent values(线段树+离散化)
- POJ3368-Frequent values-离散化+线段树
- HDU 1806 Frequent values(线段树+离散化+二分)
- poj 3368 Frequent values(线段树+离散化) -
- poj 3368 Frequent values(离散化+线段树区间求最值)
- poj 3368 Frequent values 线段树 离散化
- 区间离散化+线段树区间求最值poj 3368 Frequent values
- POJ 3368 Frequent values(线段树)
- poj 3368 Frequent values(线段树)
- POJ 3368 Frequent values(线段树)
- poj-3368-Frequent values-(线段树)
- POJ3368 Frequent values 线段树
- poj3368 Frequent values(线段树)
- Frequent values poj3368 线段树
- poj 3368 Frequent values(离散化+RMQ)
- poj 3386 -- Frequent values (RMQ/线段树)
- hdu 1806 Frequent values(二分+线段树)
- poj 3368 Frequent values(线段树解法)
- 【LeetCode】C# 47、Permutations II
- Spark-Sql版本升级对应的新特性汇总
- CodeIgniter 入门实践(博客站-2:多视图)
- 模糊控制数学基础(模糊推理)
- VS+OPENCV+imageWatch 强烈推荐给opencv开发的小伙伴!
- Frequent values(线段树+离散化)
- sdut 3333 数据结构实验之栈与队列六:下一较大值(二)
- Java中的ModBus CRC16校验
- C#--Winform项目核心模块--考勤模块
- 运用java的数组实现 多项式加法 java数组 编程习题
- linux内核进程调度
- 眼底图像血管增强与分割--(1)匹配滤波算法原理及实现
- 安装pip-9.0.1-py2.py3-none-any.whl
- JavaScript面向对象程序设计——属性