Frequent values

原创 2016年08月30日 20:09:37
链接:http://poj.org/problem?id=3368

题目: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.

题意:给一串数字(升序),求任意区间内出现次数最多的数字出现的次数。

分析:靠这道题终于第一次临摹了线段树,虽然没有用到lazy算法。这个线段树的手法不是很标准,因为按照升序排列,所以线段是拍好的,不需要维护修改,所以叶子结点直接存储每个线段的长度,其他节点保存其子孙里最长的线段长度。这样在计算任意区间的时候最多比较三次,左侧的不完全线段,右侧的不完整线段,以及中间完整线段中的最长线段长度(这个用线段树的性质容易得到)。在计算的时候要维护一个前缀和来计算区间端点所在的叶节点位置,以及用来计算左右不完整线段的长度。

题解:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <cmath>
#include <cctype>
#include <cfloat>
#include <climits>
#include <complex>
#include <deque>
#include <list>
#include <set>
#include <utility>
#define rt return
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
#define ull unsigned long long
#define detie ios_base::sync_with_stdio(false);cin.tie(false);cout.tie(false)
#define pii pair<int,int>
#define lowbit(x) x&(-x)
using namespace std;
#define maxi 0x3f3f3f3f
#define MAX 100010

int v[MAX], sum[MAX];
int n, q, cnt;

struct tree
{
	int l, r, m;
	tree() {};
	tree(int a, int b, int c) {
		l = a, r = b, m = c;
	}
}a[4 * MAX];

void build(int l, int r, int root) 
{
	a[root].l = l;
	a[root].r = r;
	if (l == r)
		a[root].m = v[l];
	else {
		int mid = (l + r) / 2;
		build(l, mid, 2 * root);
		build(mid + 1, r, 2 * root + 1);
		a[root].m = max(a[2 * root].m, a[2 * root + 1].m);
	}
}

int querry(int l, int r, int root)
{
	if (l <= a[root].l&&a[root].r <= r){
		rt a[root].m;
	}
	else {
		int mid = (a[root].l + a[root].r) / 2;
		if (r <= mid)rt querry(l, r, 2 * root);
		else if (l > mid)rt querry(l, r, 2 * root + 1);
		else rt max(querry(l, mid, 2 * root), querry(mid + 1, r, 2 * root + 1));
	}
}

int binary_search(int k)
{
	int l = 1, r = cnt;
	while (l < r)
	{
		int mid = (l + r) / 2;
		if (sum[mid] >= k){
			r = mid;
		}
		else {
			l = mid + 1;
		}
	}
	return l;
}

int main()
{
	//fr;
	detie;
	while (~scanf("%d", &n) && n)
	{
		memset(a, 0, sizeof a);
		memset(v, 0, sizeof v);
		memset(sum, 0, sizeof sum);
		cnt = 0;
		scanf("%d", &q);
		int pre, num;
		pre = maxi;
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &num);
			if (num == pre)
				v[cnt]++;
			else {
				v[++cnt]++;
				pre = num;
			}
		}
		for (int i = 1; i <= cnt; i++)
		{
			sum[i] = sum[i - 1] + v[i];
		}
		build(1, cnt, 1);
		while (q--)
		{
			int i, j, ans;
			scanf("%d %d", &i, &j);
			int L = binary_search(i);
			int R = binary_search(j);
			if (L == R)
				printf("%d\n", j - i + 1);
			else {
				ans = max(sum[L] - i + 1, j - sum[R - 1]);
				if (L <= R - 2) {
					ans = max(ans, querry(L + 1, R - 1, 1));
				}
				printf("%d\n", ans);
			}
		}
	}
	rt 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

【POJ】3368-Frequent values(RMQ或线段树)

RMQ和线段树都能过,而且时间都500MS左右。 这道题主要还是思路的问题,特殊处理l,r所在的区间,中间的区间就用线段树区间求最值解决,想上去了代码很好实现。 RMQ代码: #include ...
  • u013451221
  • u013451221
  • 2014年09月22日 19:41
  • 634

11235 - Frequent values

《算法竞赛入门经典-训练指南》P198 记录一下区间的左右边界就可以了 #include #include #include #include #include #include #inc...
  • moyan_min
  • moyan_min
  • 2013年10月12日 21:13
  • 1291

poj 3368 Frequent values(线段树解法)

题目链接:http://poj.org/problem?id=3368 题目大意:给你一段不下降的序列,求给定区间里出现次数最多的那个数字的次数。 思路:首先看到这题时,第一感觉线...
  • u010304217
  • u010304217
  • 2014年07月29日 20:03
  • 965

UVA11235:Frequent values(RMQ)

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to th...
  • libin56842
  • libin56842
  • 2015年06月13日 15:32
  • 1766

UVa 11235 - Frequent values

Sparse-Table算法入门题,只不过这里的最小值变成了最大值。
  • crazysillynerd
  • crazysillynerd
  • 2015年02月26日 09:27
  • 310

POJ1201-Intervals-线段树+贪心

原题链接 题意:给定一些区间,每个区间里必须取ci个数,这些数组成一个集合z,求z的最少的元素数 思路:由于如果两个区间如果有重复取的元素,那么这个元素一定是在左边的这个区间的最右边的那些元素。所...
  • qq_31805821
  • qq_31805821
  • 2017年02月22日 16:34
  • 124

Frequent values

Frequent values Description You are given a sequence of n integers a1 , a2 , ... , an in non-decre...
  • zhangleijava1
  • zhangleijava1
  • 2013年11月01日 14:21
  • 493

hdu1806——Frequent values

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to th...
  • c_circle
  • c_circle
  • 2017年08月19日 14:05
  • 46

poj Frequent values 3368

Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17832 ...
  • qq_34952846
  • qq_34952846
  • 2016年12月06日 11:45
  • 89

POJ 3368 Frequent values

RMQ问题第二题,还是用线段树写的,DP很渣ST算法看不懂啊~~ 题目大意: 给出依次不下降的n个数,求某个区间内出现次数最多的数字的个数。 解题思路: 这题用线段树写的话如果...
  • lin375691011
  • lin375691011
  • 2014年03月25日 14:46
  • 5637
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Frequent values
举报原因:
原因补充:

(最多只允许输入30个字)