poj3368 Frequent values

思路:

转化为RMQ。

实现:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int MAXN = 100005;
 6 const int INF = 0x3f3f3f3f;
 7
 8 int a[MAXN], tree[MAXN * 4], n, m, sum[MAXN];
 9
10 void build(int num, int l, int r)
11 {
12     if (l == r) { tree[num] = a[l]; return; }
13     int m = l + r >> 1;
14     build(num * 2, l, m);
15     build(num * 2 + 1, m + 1, r);
16     tree[num] = max(tree[num * 2], tree[num * 2 + 1]);
17 }
18
19 int query(int num, int l, int r, int x, int y)
20 {
21     if (x <= l && y >= r) return tree[num];
22     int ans = -INF, m = l + r >> 1;
23     if (x <= m) ans = max(ans, query(num * 2, l, m, x, y));
24     if (y >= m + 1) ans = max(ans, query(num * 2 + 1, m + 1, r, x, y));
25     return ans;
26 }
27
28 int main()
29 {
30     while (scanf("%d", &n), n)
31     {
32         memset(a, 0, sizeof a);
33         memset(sum, 0, sizeof sum);
34         scanf("%d", &m);
35         int last = -INF, tmp, now = 0;
36         for (int i = 1; i <= n; i++)
37         {
38             scanf("%d", &tmp);
39             if (tmp == last) a[now]++;
40             else last = tmp, a[++now]++;
41         }
42         build(1, 1, now);
43         for (int i = 1; i <= now; i++) sum[i] = sum[i - 1] + a[i];
44         int l, r;
45         for (int i = 0; i < m; i++)
46         {
47             scanf("%d %d", &l, &r);
48             int ls = lower_bound(sum, sum + now + 1, l) - sum;
49             int rs = lower_bound(sum, sum + now + 1, r) - sum;
50             int ans = -1;
51             if (ls == rs) ans = r - l + 1;
52             else
53             {
54                 ans = max(sum[ls] - l + 1, r - sum[rs - 1]);
55                 if (rs - ls > 1) ans = max(ans, query(1, 1, now, ls + 1, rs - 1));
56             }
57             printf("%d\n", ans);
58         }
59     }
60     return 0;
61 }

原文地址:https://www.cnblogs.com/wangyiming/p/8455107.html

时间: 2024-11-09 02:44:38

poj3368 Frequent values的相关文章

POJ3368 Frequent values 线段树

N个数为非递减顺序,给定范围l,r,求[l,r]区间内数字出现频率最高的次数. 可以用线段树来做.先说查询,我们设节点P对应的区间为[a, b],左孩子节点为p1,右孩子节点为p2,那么 P也许不等于 max(p1 , p2),原因是如果p1中频率较低的某个数与p2中出现频率较低的某个数是同一个数,并且两者出现次数加起来大于max(p1, p2),但是,题目说N个数为非递减顺序排列,所以这个可能只会发生在p1的右端和p2的左端对应的数是同一个数,因此,我们还要处理这第三个可能. 查询的问题解决,

POJ3368 Frequent values(RMQ线段树)

题目大概说给一个递增序列,询问区间出现最多的数. 用莫队算法比较直观,虽然应该会T..好像也可以主席树..不过题目给的序列是有序的,因而相同的数会聚在一起. 考虑把序列分成一段一段,使每段都包含极大的相同的数字 这样对于每一个区间查询: 可能这个区间左边或右边没有包含完整的一段,而其长度在段里对左或右端点进行二分查找就知道了 而除去两边不完整的,还要求出中间若干完整段的最大长度,这个就是用RMQ来快速解决了 于是这题就能这样解决了. 1 #include<cstdio> 2 #include&

[poj3368]Frequent values(rmq)

题意:给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数. 解题关键:统计次数,转化为RMQ问题,运用st表求解,注意边界. 预处理复杂度:$O(n\log n)$ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream>

POJ 3368:Frequent values RMQ

Frequent values 题目链接: http://poj.org/problem?id=3368 题意: 给出一个非递减序列,求区间内最多的数字的数量 题解: 水题,dp[i][j]记录从 i 开始2^j个数中的出现最多的数,合并dp[i][j]和dp[i+(1<<j)][j]得到dp[i][1<<(j+1)]的时候,由于序列是连续的,只要多考虑一个i+(1<<j)-1(即dp[i][j]所能到达的最右端)上得数字在区间内出现的次数就好了. 代码 #includ

uva 11235 - Frequent values(RMQ)

题目链接:uva 11235 - Frequent values 题目大意:给定一个非降序的整数数组,要求计算对于一些询问(i,j),回答ai,ai+1,-,aj中出现最多的数出现的次数. 解题思路:因为序列为非降序的,所以相同的数字肯定是靠在一起的,所以用o(n)的方法处理处每段相同数字的区间.然后对于每次询问: num[i]=num[j]:j?i+1 numi≠numj:max(RMQ(righti+1,reftj?1),max(righti?i+1,j?leftj+1)) #include

poj 3368 Frequent values(线段树解法)

题目链接:http://poj.org/problem?id=3368 题目大意:给你一段不下降的序列,求给定区间里出现次数最多的那个数字的次数. 思路:首先看到这题时,第一感觉线段树,但是仔细一看问题来啦,用线段数我怎么才能计算出某段区间里出现的那个数,因为出现最多的那个数可能不是在他它的左儿子上也不是在它的右儿子上,可能在当他们合并成一个区间时就出现啦,但是这儿我们需要注意的就是,题目给的是一段不下降的序列,那么突破口就出来啦,因为如果出现相同的数字,那么它们一定是连续的.所以我们只需要在普

POJ 3368 Frequent values

Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13051 Accepted: 4792 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 consisti

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

                                                     Frequent values 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

poj 3368 Frequent values 解题报告

题目链接:http://poj.org/problem?id=3368 题目意思:给出一段 n 个数的序列你,对于区间 [l, r] 的询问,找出 出现频率最高的数的次数.考虑到序列中的数是非递减的,也就是相同的数会连续不间断地在一起,于是就才有了代码中这个部分来预判了: if (s > t)        printf("%d\n", ans); 这个人写RMQ 写得不错:http://dongxicheng.org/structure/lca-rmq/ 这题就是套模板的,纪念