hdu 1806 Frequent values 线段树
给一个非递减数列, n个数, m个询问, 每个询问给出区间[L, R], 求这个区间里面出现次数最多的数的次数。
非递减数列, 这是最关键的一个条件...
需要保存一个区间最左边的数, 最右边的数, 最长前缀, 最长后缀, 和这个区间里面次数最多的数的次数。
一个区间出现最多的数的次数, 应该是左区间和右区间里面取一个最大值。 如果左区间最右边的数和右区间最左边的数相同, 还需要判断这个数左右区间加起来的数量是否大于最大值。
合并的时候需要判断左区间最右边的数和右区间最左边的数是否相同, 具体看代码。
#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
int lnum[maxn<<], rnum[maxn<<], maxx[maxn<<], pre_max[maxn<<], suf_max[maxn<<];
void pushUp(int rt, int m) {
maxx[rt] = max(maxx[rt<<], maxx[rt<<|]);
lnum[rt] = lnum[rt<<];
rnum[rt] = rnum[rt<<|];
suf_max[rt] = suf_max[rt<<|];
if(suf_max[rt] == (m>>)&&lnum[rt<<|] == rnum[rt<<]) //如果左区间最右边的数和右区间最左边的数相等
suf_max[rt] += suf_max[rt<<]; //并且左区间的后缀长度等于这段区间的长度
pre_max[rt] = pre_max[rt<<];
if(pre_max[rt] == m-(m>>) && rnum[rt<<] == lnum[rt<<|])
pre_max[rt] += pre_max[rt<<|];
if(lnum[rt<<|] == rnum[rt<<])
maxx[rt] = max(maxx[rt], pre_max[rt<<|]+suf_max[rt<<]);
}
void build(int l, int r, int rt) {
if(l == r) {
scanf("%d", &lnum[rt]);
rnum[rt] = lnum[rt];
maxx[rt] = pre_max[rt] = suf_max[rt] = ;
return ;
}
int m = l+r>>;
build(lson);
build(rson);
pushUp(rt, r-l+);
}
int query(int L, int R, int l, int r, int rt) {
if(L<=l&&R>=r) {
return maxx[rt];
}
int m = l+r>>;
if(R<=m)
return query(L, R, lson);
if(L>m)
return query(L, R, rson);
int tmp1 = query(L, m, lson);
int tmp2 = query(m+, R, rson);
int tmp3 = ;
if(lnum[rt<<|] == rnum[rt<<])
tmp3 = min(pre_max[rt<<|], R-m)+min(suf_max[rt<<], m-L+);
return max(tmp1, max(tmp2, tmp3));
}
int main()
{
int n, m;
while(cin>>n&&n) {
cin>>m;
build(, n, );
while(m--) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", query(x, y, , n, ));
}
}
return ;
}
hdu 1806 Frequent values 线段树的更多相关文章
- HDOJ-1806 ( Frequent values ) 线段树区间合并
http://acm.hdu.edu.cn/showproblem.php?pid=1806 线段树维护区间出现频率最高的出现次数.为了维护上者,需要维护线段前后缀的出现次数,当和其他线段在端点处的字 ...
- [HDU 1806] Frequent values
Frequent values Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- UVA 11235 Frequent values 线段树/RMQ
vjudge 上题目链接:UVA 11235 *******************************************************大白书上解释**************** ...
- POJ 3368 Frequent values 线段树与RMQ解法
题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...
- POJ3368(Frequent values)--线段树
题目在这里 3368 Accepted 7312K 1829MS C++ 6936B 题意为给你一组数据,再给定一组区间,问你这个区间内出现次数最多的元素的次数是多少. 我还记得这题是学校校赛基础的题 ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4578 - Transformation - [加强版线段树]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 Problem Description Yuanfang is puzzled with the ...
随机推荐
- JavaScript小知识点(一)
JavaScript 有3种方式定义对象 ① var i = { function-x:function{ //todo }}; 这是通过Json方式定义一个函数对象. ② function P ...
- 为什么用户主目录下.bash_profile没有自动执行
请注意 一般登录当前用户后 .bash_profile会自动运行 如果不自动运行请查看是不是切换用户的时候使用的su 用户名而不是su - 用户名 添加中间这个 - 后 会除了切换用户外还会加载该用户 ...
- OpenCV系列--摄像头控制的简单代码
操作系统:windows xp 开发工具:VS2008 opencv版本:2.1.0 依赖库:OpenCV2.1\lib\highgui.lib #include "cv.h" # ...
- Ubuntu下使用Vi时方向键变乱码 退格键不能使用的解决方法
要在Ubuntu下编辑一些文件,这就涉及到了vi这个编辑器了.在Ubuntu下,初始使用vi的时候有点问题,就是在编辑模式下使用方向键的时候,并不会使光标移动,而是在命令行中出现[A [B [C [D ...
- jquery学习(2)--选择器
jquery-李炎恢学习视频学习笔记.自己手写. 简单的选择器 css 写 法: #box{ color:#f00;} //id选择器 jquery获取:$('#box').css( ...
- (译) 《Javascript 24条最佳实践》
(摘录) <Javascript 24条最佳实践> 自己一直偏向于实用主义,不是学院派,不是学究派,只讲究把东西能够很好的做出来,但经过一段时间的开发工作当自己总结出来一些东西时,觉得挺有 ...
- c语言中 %p的含义
格式控制符“%p”中的p是pointer(指针)的缩写.指针的值是语言实现(编译程序)相关的,但几乎所有实现中,指针的值都是一个表示地址空间中某个存储器单元的整数.printf函数族中对于%p一般以十 ...
- android 添加左右滑屏手势
今天要在自己的项目中添加左右滑动,实现日期的加减(原来已经做了加减按键).滑动在一个中间的layout中进行 思路:添加左右划屏幕判断,得到判断后模拟加减按键按下. 模拟按键按下用 mbotton.p ...
- erlang supervisor说明
Supervisor Behaviour是一个用来实现一个supervisor进程来监控其他子进程的模块 子进程可以是另一个supervisor,也可以是一个worker进程. worker进程一般使 ...
- qutIm编译
官网:http://www.qutim.org/ 原文地址:http://wiki.qutim.org/en/building_from_git 依赖: Qt4-dev 4.7:http://qt-p ...