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;
}


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

相关文章推荐

poj3368 Frequent values(维护个最大值rmq or 线段树)

题意: 给你一个n个非递减的整数序列a1,a2,…… 假设给你个区间[i,j](1)。对于每个区间,你需要确定最频繁的数a[x](i int c[100010];每个数字第一次出现的位置 int ...

POJ 3368-Frequent values(RMQ+离散化-最频繁的元素)

Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18533 ...
  • MIKASA3
  • MIKASA3
  • 2017年04月12日 17:36
  • 302

UVa:11235 Frequent values

RMQ问题。用稀疏表解决的,思路照搬了白书上的。。 #include #include #include #include #include #include #includ...
  • kkkwjx
  • kkkwjx
  • 2014年01月24日 13:02
  • 578

UVA 11235 Frequent values(RMQ)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem...

POJ 3368 Frequent Values

查询区间内满足要求的连续的最大一段的长度

poj 3368 Frequent values

题意:给你n从小到大的树,查询一个区间的最长的连续长度思路:离散化,转换成rmq问题其实这个题会有三种情况(红色表示你要查询的段)1:-1 -1 1 1 1 1 3 3 3 3 10 10 10...
  • Euler_M
  • Euler_M
  • 2011年03月29日 21:50
  • 349

uva 11235 Frequent values RMQ

代码: #include #include #include #include #include #include #include #include #include #incl...

poj 3368 Frequent values //线段树

 Frequent valuesTime Limit: 2000MS Memory Limit: 65536KTotal Submissions: 7308 Accepted: 2615Descrip...
  • hqd_acm
  • hqd_acm
  • 2011年04月14日 20:09
  • 625

uva 11235 Frequent Values(游程编码, RMQ)

因为序列非降,所以相等的元素聚在一起,可以用

poj 3368 Frequent values(线段树解法)

题目链接:http://poj.org/problem?id=3368 题目大意:给你一段不下降的序列,求给定区间里出现次数最多的那个数字的次数。 思路:首先看到这题时,第一感觉线...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Frequent values
举报原因:
原因补充:

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