题目链接: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 统计次数) 详细讲解的更多相关文章

  1. poj 3368 Frequent values(RMQ)

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

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

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

  3. POJ 3368 Frequent values(RMQ 求区间出现最多次数的数字的次数)

    题目链接:http://poj.org/problem? id=3368 Description You are given a sequence of n integers a1 , a2 , .. ...

  4. POJ 3368 Frequent values RMQ 训练指南 好题

    #include<cstdio> #include<cstring> ; const int inf=0x3f3f3f3f; inline int max(int x,int ...

  5. RMQ算法 以及UVA 11235 Frequent Values(RMQ)

    RMQ算法 简单来说,RMQ算法是给定一组数据,求取区间[l,r]内的最大或最小值. 例如一组任意数据 5 6 8 1 3 11 45 78 59 66 4,求取区间(1,8)  内的最大值.数据量小 ...

  6. POJ 3368 Frequent values (基础RMQ)

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

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

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

  8. [HDU 1806] Frequent values

    Frequent values Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. poj 3368 Frequent values(段树)

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

随机推荐

  1. Nokitjs 系列-01 - HelloWorld

    一.前言 本篇文章需要读者有一点 Node.js 基础的了解,并且已经安装了 Node.js (node.npm),但并不需要有 Nokit 的知识,本文将简单介绍 Nokitjs 的安装使用,并编写 ...

  2. redux状态管理和react-redux的结合使用

    一:调试 注意:Redux调试工具.谷歌中搜redux同理react 新建store的时候判断window.devToolsExtension使用compose(组合函数)结合thunk插件和wind ...

  3. Ubuntu下Firefox无法播放视频的解决方法

    Ubuntu为Firefox安装Adobe Flash Player 解决方法(解决火狐浏览器安装了三个flash插件中的第二个或者第三个插件而无法安装第一个adobe flash插件的方法):在新立 ...

  4. [转]ssis cannot retrieve the column code page info from the ole db provider

    本文转自:http://social.msdn.microsoft.com/Forums/sqlserver/en-US/dc1a61f2-1ab8-4ed3-b85c-db6481800b50/er ...

  5. 使用虚拟机运行Ubuntu时,主机与宿主机共享文件的方法。

    简介: 首先设置虚拟机: 虚拟机 -> 设置-> Hardware -> Network Adapter,在网络连接处设置为 “桥接:直接连接到物理网络”,“NAT:使用已共享的主机 ...

  6. Hadoop 添加删除Slave

    Hadoop 添加删除Slave @(Hadoop) 在hdfs-site.xml文件中添加如下配置: <property> <name>dfs.hosts</name& ...

  7. spfile 和用户环境变量 和export

    RAC数据库环境变量设置 [oracle@rac1 ~]$ sqlplus / as sysdba  SQL*Plus: Release 10.2.0.1.0 - Production on Fri ...

  8. CentOS 6.5 源码安装subversion-1.8.8,附加mod_dav_svn模块

    题记:第一次写如此实践类的博文,都是亲身经历,折腾了大半天,仅记录供参考.(新手实践,有错误之处欢迎纠正.) 安装前准备: 1.已安装JDK1.7,并配置好环境变量. 2.已安装apr.apr-uti ...

  9. FastDFS安装配置过程中出现错误提示"/home/yuqing/fastdfs" can't be accessed, error info: No such file or directory

    解决: mkdir -p /home/yuqing/fastdfs 这回正常了,查看启动成功与否 [root@localhost FastDHT]# ps -ef |grep track |grep ...

  10. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)如何修改标准驱动器编码器分辨率

    在某个轴的Enc上双击,可以修改Scaling Factor Numerator     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/acetao ...