poj 1806 Frequent values(RMQ 统计次数) 详细讲解
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1806
题目大意:给你一个非降序排列的整数数组,你的任务是对于一系列的询问,(i,j),回答序列中出现次数最多的数的个数;
如下图所示:

AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
const int N = 1e5+;
int a[N],b[N];
int dp[N][];
int n,m;
//构造和寻找的代码,来自大白书
void buildrmq( )
{
for(int i=;i<n;i++)
dp[i][]=b[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<n;i++)
dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
}
int search(int s,int v)
{
int k = ;
while(<<(k+) <= v-s+) k++;
return max(dp[s][k],dp[v-(<<k)+][k]);
}
int bi_search(int s,int t)
{
int tmp=a[t];
int l=s;
int r=t;
int mid;
while(l<r)
{
mid=((l+r)>>);
if(a[mid]>=tmp) r=mid;
else l=mid+;
}
return r;
}
int main()
{
int T;
while(scanf("%d",&n) && n)
{
memset(b,,sizeof(b));
memset(dp,,sizeof(dp));
scanf("%d",&m);
for(int i =; i<n; i++)
scanf("%d",&a[i]);
a[n] = a[n-]+;
for(int i =n-; i>=; i--)//倒序统计单个数在当前段出现的次数
{
if(a[i] == a[i+])
{
b[i] = b[i+]+;
}
else b[i] =;
}
buildrmq( );//构造RMQ函数
int L,R,ans;
for(int i=; i<=m; i++)
{
scanf("%d %d",&L,&R);
L = L-;R = R-;//题目中是从1开始计数的;
int temp = bi_search(L,R);//寻找数组中最左端等于a[R]的数
ans = b[temp] - b[R]+; //统计和最左边相同的数出现的次数
if(L == temp) printf("%d\n",ans);//如果这一区间中的数字相同的话,直接左边减去右边
else printf("%d\n",max(ans,search(L,temp-)));//否则,寻找(L,temp)中的最大数,进行比较
}
}
return ;
}
AC代码2:线段树
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e5+;
int a[N];
int ans ;
struct node
{
int L,R,count,fre;
int lcount,lfre;
int rcount,rfre;
}tree[*N];
/*
l,r存该节点的边界。
count存该节点中出现最多的数字的个数,fre存该节点中出现最多的数字。
lcount 存该节点左端连续出现的数字的个数, lfre存该节点左端连续出现的数字。
rcount 存该节点右端连续出现的数字的个数, rfre存该节点右端连续出现的数字。
*/
void build(int l,int r,int v)
{
tree[v].L = l;
tree[v].R = r;
if(l == r)
{
tree[v].fre = tree[v]. rfre = tree[v].lfre = a[r];
tree[v].count = tree[v].lcount = tree[v].rcount = ;
return ;
}
int mid = (l+r)/;
build(l,mid,v*);
build(mid+,r,v*+);
int tmpc,tmpf;
if(tree[v*].count>tree[v*+].count)
{
tree[v].count = tree[v*].count;
tree[v].fre = tree[v*].fre;
}
else
{
tree[v].count = tree[v*+].count;
tree[v].fre = tree[v*+].fre;
}
tree[v].lcount = tree[v*].lcount;
tree[v].rcount = tree[v*+].rcount;
if(tree[v*].rfre == tree[v*+].lfre)
{
tmpc = tree[v*].rcount +tree[v*+].lcount;
tmpf = tree[v*].rfre;
if(tree[v].count<tmpc)
{
tree[v].count = tmpc;
tree[v].fre = tmpf;
}
if(tree[v*].lfre == tree[v*+].lfre)
tree[v].lcount = tree[v].lcount+tree[v*+].lcount;
if(tree[v*].rfre == tree[v*+].rfre)
tree[v].rcount= tree[v*].rcount+tree[v].rcount;
}
tree[v].lfre = tree[v*].lfre;
tree[v].rfre = tree[v*+].rfre;
}
void update(int x,int y,int v)
{
int mid,s1,s2;
if(tree[v].L == x && tree[v].R == y)
{
if(tree[v].count>ans)
ans = tree[v].count;
return ;
}
mid = (tree[v].L+tree[v].R)/;
if(y<=mid) update(x,y,v*);
else if(x>mid) update(x,y,v*+);
else {
update(x,mid,v*);
update(mid+,y,v*+);
if(tree[v*].rfre == tree[v*+].lfre)
{
if(a[x] != tree[v*].rfre) s1 = tree[v*].rcount;
else s1 = mid-x+;
if(a[y]!=tree[v*+].lfre) s2 = tree[v*+].lcount;
else s2 = y - mid;
if(s1+s2>ans) ans = s1+s2;
}
}
}
int main()
{
int m,n,x,y;
while(scanf("%d",&m) && m)
{
scanf("%d\n",&n);
for(int i=;i<=m;i++)
scanf("%d",&a[i]);
build(,m,);
for(int i=;i<=n; i++)
{ ans = ;
scanf("%d %d",&x,&y);
if(x==y) {printf("1\n");continue;}
update(x,y,);
printf("%d\n",ans);
}
}
return ;
}
poj 1806 Frequent values(RMQ 统计次数) 详细讲解的更多相关文章
- poj 3368 Frequent values(RMQ)
/************************************************************ 题目: Frequent values(poj 3368) 链接: http ...
- POJ 3368 Frequent values RMQ ST算法/线段树
Frequent values Time Limit: 2000MS Memory Lim ...
- POJ 3368 Frequent values(RMQ 求区间出现最多次数的数字的次数)
题目链接:http://poj.org/problem? id=3368 Description You are given a sequence of n integers a1 , a2 , .. ...
- POJ 3368 Frequent values RMQ 训练指南 好题
#include<cstdio> #include<cstring> ; const int inf=0x3f3f3f3f; inline int max(int x,int ...
- RMQ算法 以及UVA 11235 Frequent Values(RMQ)
RMQ算法 简单来说,RMQ算法是给定一组数据,求取区间[l,r]内的最大或最小值. 例如一组任意数据 5 6 8 1 3 11 45 78 59 66 4,求取区间(1,8) 内的最大值.数据量小 ...
- POJ 3368 Frequent values (基础RMQ)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14742 Accepted: 5354 ...
- POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】
传送门:http://poj.org/problem?id=3368 Frequent values Time Limit: 2000MS Memory Limit: 65536K Total S ...
- [HDU 1806] Frequent values
Frequent values Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- poj 3368 Frequent values(段树)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13516 Accepted: 4971 ...
随机推荐
- 解决kylin报错 ClassCastException org.apache.hadoop.hive.ql.exec.ConditionalTask cannot be cast to org.apache.hadoop.hive.ql.exec.mr.MapRedTask
方法:去掉参数SET hive.auto.convert.join=true; 从配置文件$KYLIN_HOME/conf/kylin_hive_conf.xml删掉 或 kylin-gui的cube ...
- Hive:用Java代码通过JDBC连接Hiveserver
参考https://www.iteblog.com/archives/846.html 1.hive依赖hadoop,将hdfs当作文件存储介质,那是否意味着hive需要知道namenode的地址? ...
- [转]Mapping Stored Procedure Parameters in SSIS OLE DB Source Editor
本文转自:http://geekswithblogs.net/stun/archive/2009/03/05/mapping-stored-procedure-parameters-in-ssis-o ...
- unity lightmap
indirect light /shadow /ao light probe for dynamic 或者细小琐碎的物体 ========================== unity2018.3 ...
- Spark SQL 代码简要阅读(基于Spark 1.1.0)
Spark SQL允许相关的查询如SQL,HiveQL或Scala运行在spark上.其核心组件是一个新的RDD:SchemaRDD,SchemaRDDs由行对象组成,并包含一个描述此行对象的每一列的 ...
- 【实践】js封装 jq siblings 方法
思路: 1.获取调用元素的父元素下的所有子元素(即它的所有同辈元素和调用元素本身) 2.遍历调用元素父元素下的所有子元素 除调用元素外的所有元素保存在一个数组里面 代码如下: <!DOCTYPE ...
- PHP Variable Scope
原文: https://phppot.com/php/variable-scope-in-php/ Last modified on March 24th, 2017 by Vincy. ------ ...
- Linux内核project导论——linux学习和职业曲线(刚開始学习的人,中级,高级都可參考)
Linux世界介绍 给自己定级 门外汉: 不会安装操作系统 不会用虚拟机(安装和使用) 入门级: 熟悉常见的发行版,甚至装过而且能用一些特殊发行版(比如kali)做过一些简单的图形界面的使用. 会一些 ...
- Junit核心——测试类(TestCase)、测试集(TestSuite)、测试运行器(TestRunner)
首先,把这三个定义简单的说明一下: 1.测试类(TestCase):一个包含一个或是多个测试的类,在Junit中就是指的是包含那些带有@Test注解的方法的类,同一样也被称作“测试用例”; 2.测试集 ...
- WIN7如何查找网络打印机
1 在开始菜单中输入"打印机"并点击"添加打印机" 2 点击下面一个,并搜索家庭组的打印机,一般可以搜到(注意这台电脑不能关机或睡眠). 3 查找并添加会需要安 ...