一 题意:给定递增序列,找出连续出现的最长子序列,然后求出它的长度,即最高频率。注意必须是连续出现。
二 算法:可以事先求出序列中每个数字的最高频率,比如序列(-1,-1,1,1,1,1,3,10,10,10)中各个数字的最高频率为:
(-1: 2), (1: 4), (3: 1), (10, 3),对于区间[s,t],仅首部和尾部有可能是从同一个数字中截断的,去掉首尾后的中间部分数字的
最高频率可以直接得到。最后比较首部,尾部,和中间部分的频率,就可以得到[s,t]的最高频率了,分三种情况讨论:
有色部分为要查找的区间[s,t],红色代表首部,蓝色代表尾部,绿色代表中间部分
1) 1111111111111
只有一种数字,直接返回(t-s+1)
2) 1111122222222222
去掉首部和尾部后,没有中间部分,直接返回首部频率和尾部频率的最大值
3) 111111222333444444
去掉首部和尾部后,中间部分为222333,在线段树中查找2和3的最高频率,综合首部尾部频率,得到答案。
问题的关键在于查找中间部分的最高频率,设中间部分有N个不同的数字,如果对每个数字都扫描一遍,算法复杂度
为O(N),必然超时,处理的时候,先把序列离散话,即把连续出现的数字聚集到一点,并计算它的频率,这样原序列转
化为一系列点集,比起原系列来,这个点集小得多,然后对这些点集根据建立线段树,线段存储的是点区间内的最高频率。
从线段树中查找,算法复杂度变为O(logN)
三 代码
#include <stdio.h>
//#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
#define MAX(a, b) (a) > (b) ? (a) : (b)
#define inf 20000000
#define N 100001
int tree[262144]; /* 保存每条线段的最高频率 */
int pos[N]; /* pos[i] = j 表示i在离散表中的位置为j */
/* 区间[l,r]内的数相同,都是num */
struct node {
int l, r;
int num;
};
struct node table[N];
int M;
void build_tree(int n)
{
int i;
for (M = 1; M < (n+2); M <<= 1);
//存储数据的叶子节点
for (i = 1; i <= n; i++) {
tree[i+M] = (table[i].r-table[i].l+1);
}
//不用的叶子节点
for (i = n+1; i%M != 1; i++) {
tree[(i%M)+M] = -1;
}
//分支节点
for (i = M-1; i > 0 ; i--) {
tree[i] = MAX(tree[i<<1], tree[(i<<1)+1]);
}
}
int query(int s, int t)
{
int max_freq;
max_freq = -1;
for (s = s+M-1, t = t+M+1; (s^t) != 1; s >>= 1, t >>= 1) {
if (~s&1) {
max_freq = MAX(max_freq, tree[s^1]);
}
if (t&1) {
max_freq = MAX(max_freq, tree[t^1]);
}
}
return max_freq;
}
int main()
{
int n, p, q, i, s, t, ans, ss, tt, num;
while (scanf("%d %d", &n, &q), n) {
table[p = 0].num = inf;
//输入,离散化
for (i = 1; i <= n; i++) {
scanf("%d", &num);
if (num == table[p].num) {
table[p].r = i;
pos[i] = p;
}
else {
p++;
table[p].l = table[p].r = i;
table[p].num = num;
pos[i] = p;
}
}
build_tree(p);
while (q--) {
scanf("%d %d", &s, &t);
//[s,t]内只有一种数
if (pos[s] == pos[t]) {
ans = (t-s+1);
}
else {
ans = -inf;
/* [s,t]内至少有两种数,把首尾两种数去掉
* 然后查询剩下的数的区间[ss,tt]
*/
ss = table[pos[s]].r+1;
tt = table[pos[t]].l-1;
if (tt >= ss) {
ans = query(pos[ss], pos[tt]);
}
ans = MAX(ans, MAX(ss-s, t-tt));
}
printf("%d\n", ans);
}
}
return 0;
}
分享到:
相关推荐
* 坐标离散化:POJ3429 * 代码快速写成,精简但不失风格:POJ2525、POJ1684、POJ1421、POJ1048、POJ2050、POJ3306 * 保证正确性和高效性:POJ3434 六、动态规划 * 需要用数据结构优化的动态规划:POJ2754、POJ3378...
1. 坐标离散化(poj3429) 2. 几何公式 3. 叉积和点积的运用(如线段相交的判定,点到线段的距离等) 六、动态规划 1. 需要用数据结构优化的动态规划 2. 四边形不等式理论 七、综合题 1. 组合数学 2. 博奕论 3. ...
7.2 线段树 147 7.3 并查集 151 7.4 树状数组 152 7.5 点树 154 7.6 STL 156 7.7 离散化 157 8.图论 158 8.0 2-SAT 158 8.2 寻找Euler回路 163 8.3 拓扑排序 163 8.4 差分约束系统 164 8.5 笛卡尔树 165 8.6 LCA和...
pandas whl安装包,对应各个python版本和系统(具体看资源名字),找准自己对应的下载即可! 下载后解压出来是已.whl为后缀的安装包,进入终端,直接pip install pandas-xxx.whl即可,非常方便。 再也不用担心pip联网下载网络超时,各种安装不成功的问题。
基于java的大学生兼职信息系统答辩PPT.pptx
基于java的乐校园二手书交易管理系统答辩PPT.pptx
tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl
Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175
有学生和教师两种角色 登录和注册模块 考场信息模块 考试信息模块 点我收藏 功能 监考安排模块 考场类型模块 系统公告模块 个人中心模块: 1、修改个人信息,可以上传图片 2、我的收藏列表 账号管理模块 服务模块 eclipse或者idea 均可以运行 jdk1.8 apache-maven-3.6 mysql5.7及以上 tomcat 8.0及以上版本
tornado-6.1b2-cp38-cp38-macosx_10_9_x86_64.whl
Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175
matlab
基于java的毕业生就业信息管理系统答辩PPT.pptx
随着高等教育的普及和毕业设计的日益重要,为了方便教师、学生和管理员进行毕业设计的选题和管理,我们开发了这款基于Web的毕业设计选题系统。 该系统主要包括教师管理、院系管理、学生管理等多个模块。在教师管理模块中,管理员可以新增、删除教师信息,并查看教师的详细资料,方便进行教师资源的分配和管理。院系管理模块则允许管理员对各个院系的信息进行管理和维护,确保信息的准确性和完整性。 学生管理模块是系统的核心之一,它提供了学生选题、任务书管理、开题报告管理、开题成绩管理等功能。学生可以在此模块中进行毕业设计的选题,并上传任务书和开题报告,管理员和教师则可以对学生的报告进行审阅和评分。 此外,系统还具备课题分类管理和课题信息管理功能,方便对毕业设计课题进行分类和归档,提高管理效率。在线留言功能则为学生、教师和管理员提供了一个交流互动的平台,可以就毕业设计相关问题进行讨论和解答。 整个系统设计简洁明了,操作便捷,大大提高了毕业设计的选题和管理效率,为高等教育的发展做出了积极贡献。
这个数据集来自世界卫生组织(WHO),包含了2000年至2015年期间193个国家的预期寿命和相关健康因素的数据。它提供了一个全面的视角,用于分析影响全球人口预期寿命的多种因素。数据集涵盖了从婴儿死亡率、GDP、BMI到免疫接种覆盖率等多个维度,为研究者提供了丰富的信息来探索和预测预期寿命。 该数据集的特点在于其跨国家的比较性,使得研究者能够识别出不同国家之间预期寿命的差异,并分析这些差异背后的原因。数据集包含22个特征列和2938行数据,涉及的变量被分为几个大类:免疫相关因素、死亡因素、经济因素和社会因素。这些数据不仅有助于了解全球健康趋势,还可以辅助制定公共卫生政策和社会福利计划。 数据集的处理包括对缺失值的处理、数据类型转换以及去重等步骤,以确保数据的准确性和可靠性。研究者可以使用这个数据集来探索如教育、健康习惯、生活方式等因素如何影响人们的寿命,以及不同国家的经济发展水平如何与预期寿命相关联。此外,数据集还可以用于预测模型的构建,通过回归分析等统计方法来预测预期寿命。 总的来说,这个数据集是研究全球健康和预期寿命变化的宝贵资源,它不仅提供了历史数据,还为未来的研究和政策制
基于微信小程序的高校毕业论文管理系统小程序答辩PPT.pptx
基于java的超市 Pos 收银管理系统答辩PPT.pptx
基于java的网上报名系统答辩PPT.pptx
基于java的网上书城答辩PPT.pptx
婚恋网站 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B