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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被加盟网店托管骗了怎么办 善林金融倒闭投资者的钱怎么办? 微信支付密码忘了怎么办没绑卡 美团外卖没有骑手接单怎么办 发微信的"发送"没有了怎么办 华硕电脑下面的任务栏卡住了怎么办 微信登别人电脑上忘记退了怎么办 买手机买全新结果买到翻新机怎么办 苹果手机激活锁忘了id账号怎么办 淘宝很多产品都需要3c怎么办 小米mix装在兜里还能解锁怎么办 痰咳不出来憋的嘴唇紫了怎么办 京东闪电退款后不给退货怎么办 我的中国银行卡在异地被冻结怎么办 qq密保号码换了验证不了怎么办 qq登陆需要密保手机验证怎么办 微信漂流瓶被投诉收不到回复怎么办 电视的屏幕出现三条黑线怎么办 付了定金的房子不想要了怎么办 顾客刚买了东西就退怎么办 飞机票买了但是没有报团怎么办 日本寄东西回来深圳海关扣了怎么办 xp框架安装模块后无限重启怎么办 手机百度云下载的文件不见了怎么办 百度云手机号换了文件不见了怎么办 好劵app提现密码忘了要怎么办 微信上买的衣服不给退货怎么办 在微信上买的衣服不给退货怎么办 贴贴纸的地方出现色差了怎么办 贴在玻璃上的贴纸撕掉后有胶怎么办 魅族手机部分时间上划失效怎么办 别人电脑上c盘文件无权访问怎么办 网络已连接但上不了网怎么办 asp复选框选中的有重复值怎么办 邮件在邮递中出现损坏怎么办呢? 爱彩彩票资金密码忘记了怎么办 注册彩票网站忘了资金密码怎么办 电车电瓶加水后电压变低怎么办 电动车电瓶四块电池坏了一块怎么办 把小孩的玩具修坏了怎么办 电动车插头太紧了插不到底怎么办