一、题面

POJ3368

二、分析

仍然是一道只需要区间查询不需要区间修改的线段树题。

这题的题面比较特别,它是一组非减的数组。当需要去找一段区间内出现次数最多的数字时,这些数字必然是连续的,那么就可以用线段树维护区间内出现的最大次数时,同时维护两端的数字出现的次数。这样,就可以在建树的时候通过判断可能的左右子树最大值和(左子树的最右端的数的次数+右子树的最左端的数的次数),括号出现的前提是左子树维护的区间右端点的数与右子树维护的区间左端点的数相等。

保证建树建成功后,就是基本的查询了,但是需要注意的是,当mid在要查询的区间内时,因为查询的区间跨了线段树的两个区间,所以当左子树维护的右端点的值和右子树的左端点的值相等时,需要与当前最大值进行比较。

二刷这题后,补充一下,初始化的问题,每组样例过后,记得对线段树的一些标记是改变了的。

三、AC代码

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm> using namespace std; const int MAXN = 1e5; struct Node
{
int l, r;
int cntl, cntr, Max;
}segTree[MAXN<<];
int Data[MAXN], Ans; void Build(int v, int L, int R)
{
segTree[v].l = L;
segTree[v].r = R;
if(L == R)
{
segTree[v].Max = ;
segTree[v].cntl = segTree[v].cntr = ;
return;
}
int mid = (L + R) >> ;
int lc = v<<, rc = v<<|;
Build(lc, L, mid);
Build(rc, mid + , R);
int sum = ; //初始化别忘了
if(Data[segTree[lc].r] == Data[segTree[rc].l])
{
sum = segTree[lc].cntr + segTree[rc].cntl;
}
if(segTree[lc].Max > segTree[rc].Max)
segTree[v].Max = segTree[lc].Max;
else
segTree[v].Max = segTree[rc].Max;
segTree[v].Max = max(segTree[v].Max, sum);
segTree[v].cntl = segTree[lc].cntl;
segTree[v].cntr = segTree[rc].cntr;
if(Data[segTree[v].l] == Data[segTree[rc].l])
{
segTree[v].cntl += segTree[rc].cntl;
}
if(Data[segTree[v].r] == Data[segTree[lc].r])
{
segTree[v].cntr += segTree[lc].cntr;
}
} void Query(int v, int L, int R)
{
if(Ans >= segTree[v].Max)
return;
if(segTree[v].l == L && segTree[v].r == R)
{
Ans = max(Ans, segTree[v].Max);
return;
}
int mid = (segTree[v].l + segTree[v].r)>>;
if(L > mid)
{
Query(v<< | , L, R);
}
else if(R <= mid)
{
Query(v<<, L, R);
}
else
{
Query(v<<, L, mid);
Query(v<< | , mid + , R);
int temp = ;
if(Data[mid] == Data[mid + ])
{
temp = min(segTree[v<<].cntr, mid - L + );
//为什么要考虑mid-L+1,因为可能所插叙的区间并没有完全包含所有的这个数
temp += min(segTree[v<<|].cntl, R - mid);
}
Ans = max(Ans, temp);
}
} int main()
{
//freopen("input.txt", "r", stdin);
int N, Q;
while(scanf("%d", &N) == && N)
{
scanf("%d", &Q);
int L, R;
for(int i = ; i <= N; i++)
scanf("%d", &Data[i]);
Build(, , N);
for(int i = ; i < Q; i++)
{
Ans = -MAXN;
scanf("%d %d", &L, &R);
Query(, L, R);
printf("%d\n", Ans);
}
}
}

POJ_3368 Frequent values 【线段树+区间查询】的更多相关文章

  1. HDOJ-1806 ( Frequent values ) 线段树区间合并

    http://acm.hdu.edu.cn/showproblem.php?pid=1806 线段树维护区间出现频率最高的出现次数.为了维护上者,需要维护线段前后缀的出现次数,当和其他线段在端点处的字 ...

  2. UVA 11235 Frequent values 线段树/RMQ

    vjudge 上题目链接:UVA 11235 *******************************************************大白书上解释**************** ...

  3. POJ 3368 Frequent values 线段树与RMQ解法

    题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...

  4. POJ3368(Frequent values)--线段树

    题目在这里 3368 Accepted 7312K 1829MS C++ 6936B 题意为给你一组数据,再给定一组区间,问你这个区间内出现次数最多的元素的次数是多少. 我还记得这题是学校校赛基础的题 ...

  5. hdu 1806 Frequent values 线段树

    题目链接 给一个非递减数列, n个数, m个询问, 每个询问给出区间[L, R], 求这个区间里面出现次数最多的数的次数. 非递减数列, 这是最关键的一个条件... 需要保存一个区间最左边的数, 最右 ...

  6. HDU 1754 I Hate It(线段树区间查询,单点更新)

    描述 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老 ...

  7. POJ_3468 A Simple Problem with Integers 【线段树区间查询+修改】

    一.题目 POJ3468 二.分析 裸的线段树区间查询+修改. 三.AC代码 #include <cstdio> #include <iostream> #include &l ...

  8. ACM_最值差(线段树区间查询最值)

    最值差 Time Limit: 2000/1000ms (Java/Others) Problem Description: 给定N个数A1A2A3A4...AN.求任意区间Ai到Aj中的最大数与最小 ...

  9. HDU 4614 Vases and Flowers(二分+线段树区间查询修改)

    描述Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to ...

随机推荐

  1. p2598 [ZJOI2009]狼和羊的故事

    传送门 分析 起点向狼连边,羊向终点连边,边权均为inf 每个点向它四联通的点连边权萎1的边 跑最小割即可 代码 #include<iostream> #include<cstdio ...

  2. sed命令n,N,d,D,p,P,h,H,g,G,x解析2

    摘自: https://blog.csdn.net/xiexingshishu/article/details/50514132 sed命令n,N,d,D,p,P,h,H,g,G,x解析 2016年0 ...

  3. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deptDao_a' defined in class path resource [beansAndHibernate.xml]: Cannot resolve reference to bean 'sessionFact

    Error creating bean with name 'deptDao_a' defined in class path 因为更改了类的名字,所以其setter方法没有更改,需要 private ...

  4. 15 输入三个整数x,y,z,请把这三个数由小到大输出。

    题目:输入三个整数x,y,z,请把这三个数由小到大输出. public class _015ThreeNumberSort { public static void main(String[] arg ...

  5. 机器学习及其matlab实现—从基础到实践

    第1周 MATLAB入门基础 第2周 MATLAB进阶与提高 第3周 BP神经网络 第4周 RBF.GRNN和PNN神经网络 第5周 竞争神经网络与SOM神经网络 第6周 支持向量机(Support ...

  6. 编写高质量代码改善C#程序的157个建议——建议119:不要使用自己的加密算法

    建议119:不要使用自己的加密算法 很多人认为自己写的加密算法才是安全的,因为该算法只有“自己知道”.很遗憾,这是大错特错. 首先,我们不是秘密学专家,如果我们随随便便写个算法就称得上是加密算法的话, ...

  7. 编写高质量代码改善C#程序的157个建议——建议67:慎用自定义异常

    建议67:慎用自定义异常 除非有充分的理由,否则不要创建自定义异常.如果要对某类程序出错做特殊处理,那就自定义异常.需要自定义异常的理由如下: 1)方便测试.通过抛出一个自定义的异常类型实例,我们可以 ...

  8. ArrayList动态数组System.Collections命名空间下

    using System.Collections; namespace myspace { class myclass { ArrayList myList=new ArrayList(); } }

  9. vue的props 属性类似于bug的东西

    /* * @Author: shs * @Date: 2019-04-19 17:48:39 * @Last Modified by: shs * @Last Modified time: 2019- ...

  10. 适用于Java的嵌入式脚本语言

    此文已由作者赵昕授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. fakescript 轻量级嵌入式脚本语言 https://github.com/esrrhs/fakescr ...