POJ 3368 Frequent values RMQ ST算法/线段树
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 15229 | Accepted: 5550 |
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
The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q 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 10
2 3
1 10
5 10
0
Sample Output
1
4
3
Source
题意:
给你一个非递减序列。有m次询问,每次询问区间之间出现最多的数字出现的次数。
题解:
RMQ/线段树
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
using namespace std ;
typedef long long ll;
#define inf 100000
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//******************************************************************
struct ss{
int l,r,num,v;
}a[];
int counts[];
int dp[][],n,m,p;
void rmq_init()
{
memset(dp,,sizeof(dp));
for(int i=;i<=p;i++){
dp[i][]=counts[i];
}
int k=floor(log((double)n+)/log(2.0));
for(int j=;j<=k;j++)
{
for(int i=;i+(<<j)-<=p;i++)
{
int oo=i+(<<(j-));
dp[i][j]=max(dp[i][j-],dp[oo][j-]);
}
}
}
int RMQ(int x,int y)
{
int oo=floor(log((double)y-x+)/log(2.0));
return max(dp[x][oo],dp[y-(<<(oo))+][oo]);
}
void work()
{
int l,r;
for(int i=;i<=m;i++)
{
scanf("%d%d",&l,&r);
if(a[l].num==a[r].num){
cout<<r-l+<<endl;
}
else {
int ans=a[l].r-l+;
ans=max(r-a[r].l+,ans);
l=a[l].num+;
r=a[r].num-;
if(l<=r) ans=max(ans,RMQ(l,r));
cout<<ans<<endl;
}
}
}
void init()
{ int f=,r=,l=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i].v);
if(f&&a[i].v!=a[i-].v)
{
counts[p]=r-l+;
for(int j=l;j<=r;j++)
a[j].num=p,a[j].l=l,a[j].r=r;
r++;
p++;
l=r;
}
else if(f){
r++;
}
if(f==)
{
l=;
r=,f=;
p=;
} }
counts[p]=r-l+;
for(int j=l;j<=r;j++)
a[j].num=p,a[j].l=l,a[j].r=r;
// for(int i=1;i<=n;i++)cout<<counts[i]<<" ";
}
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==)break;
init();
rmq_init();
work();
}
return ;
}
RMQ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
using namespace std ;
typedef long long ll;
#define inf 100000
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//******************************************************************
struct ss
{
int l,r,v,num;
}tr[*],a[];
int counts[];
int n,m,p;
void build(int k,int s,int t)
{
tr[k].l=s;
tr[k].r=t;
if(s==t){
tr[k].v=counts[s];
return ;
}
int mid=(s+t)>>;
build(k<<,s,mid);
build(k<<|,mid+,t);
tr[k].v=max(tr[k<<].v,tr[k<<|].v);
}
int ask(int k,int s,int t)
{
if(s==tr[k].l&&t==tr[k].r)
{
return tr[k].v;
}
int mid=(tr[k].l+tr[k].r)>>;
if(t<=mid)return ask(k<<,s,t);
else if(s>mid)return ask(k<<|,s,t);
else {
return max(ask(k<<,s,mid),ask(k<<|,mid+,t));
}
}
void init()
{
int f=,l=,r=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i].v);
if(f&&a[i].v!=a[i-].v)
{
counts[p]=r-l+;
for(int j=l;j<=r;j++)a[j].l=l,a[j].r=r,a[j].num=p; r++;
l=r;
p++;
}
else if(f){
r++;
}
if(!f)
{
f=l=;
r=p=;
}
}
counts[p]=r-l+;
for(int j=l;j<=r;j++)a[j].l=l,a[j].r=r,a[j].num=p;
///for(int i=1;i<=p;i++)cout<<counts[i]<<" ";
}
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{
p=;
if(n==)break;
init();
build(,,p);
// cout<<p<<endl;
int x,y;
for(int i=;i<=m;i++)
{ scanf("%d%d",&x,&y);
if(a[x].num==a[y].num){
cout<<y-x+<<endl;
}
else {
int ans=a[x].r-x+;
ans=max(ans,y-a[y].l+);
x=a[x].num+;
y=a[y].num-;
if(x<=y)ans=max(ask(,x,y),ans);
cout<<ans<<endl;
}
}
}
return ;
}
线段树
POJ 3368 Frequent values RMQ ST算法/线段树的更多相关文章
- POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】
传送门:http://poj.org/problem?id=3368 Frequent values Time Limit: 2000MS Memory Limit: 65536K Total S ...
- poj 3368 Frequent values(RMQ)
/************************************************************ 题目: Frequent values(poj 3368) 链接: http ...
- 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 ...
- POJ 3368 Frequent values 线段树与RMQ解法
题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...
- [RMQ] [线段树] POJ 3368 Frequent Values
一句话,多次查询区间的众数的次数 注意多组数据!!!! RMQ方法: 预处理 i 及其之前相同的数的个数 再倒着预处理出 i 到不是与 a[i] 相等的位置之前的一个位置, 查询时分成相同的一段和不同 ...
- POJ 3368 Frequent values (基础RMQ)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14742 Accepted: 5354 ...
- poj 3368 Frequent values -Sparse-Table
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16537 Accepted: 5981 Description You ...
- poj 3368 Frequent values(段树)
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13516 Accepted: 4971 ...
随机推荐
- 第十三章:MFC库与Windows程序开发概述
主要内容: 1.Windows程序的基本结构 2.MFC库简介 3.使用Visual C++开发Windows程序 具体内容略
- Java自动生成asmx的webservice代码
第一种方式:针对CXF自动生成的代码对响应类大小写区别问题,可以使用此方法. 工具为Eclipse. 新建Web Service Client. 输入地址点击finish即可自动生成. 调用方式: p ...
- 3.3.2 使用 cut 选定字段
cut 命令是用来剪下文本文件里的数据,文本文件可以是字段类型或是字符类型.后一种数据类型在遇到需要从文件里剪下特定的列时,特别方便.请注意:一个制表字符在此被视为单个字符. ...
- 【03】使用 Firebug 调试 JavaScript
[03] 使用 Firebug 调试 JavaScript 描述 Firebug是一个非常强大的工具,可以帮助您发现代码发现错误的错误并解决错误. 在此我们使用Firebug来处理Javascript ...
- 大数据学习——linux常用命令(二)四
系统管理操作 1 挂载外部存储设备 可以挂载光盘.硬盘.磁带.光盘镜像文件等 1/ 挂载光驱 mkdir /mnt/cdrom 创建一个目录,用来挂载 mount -t iso9660 ...
- httpclient调用webservice接口的方法实例
这几天在写webservice接口,其他的调用方式要生成客户端代码,比较麻烦,不够灵活,今天学习了一下httpclient调用ws的方式,感觉很实用,话不多说,上代码 http://testhcm.y ...
- C#中为什么不能再方法里定义静态变量(Static)
c#的静态变量是在对象生成的时候分配内存空间的,而不是函数执行的时候. 如果在函数里定义,那么这个变量就需要在函数执行的时候分配内存空间,这是C#不允许的,至于为什么不允许,个是因为垃圾回收机制的问题 ...
- POJ 1386 单词接龙问题
题目大意: 给一堆字母,让它们进行接龙,要头对尾能够接的上,问有没有一种方法让所有成语都完成接龙 这道题实际上是在考虑是否存在一条欧拉通路,每个单词产生一条有向线段,由第一个字母指向最后一个字母 这道 ...
- 洛谷P1757 通天之分组背包
题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大 ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...