一、题面

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. Linux网络配置之虚拟网卡的配置(Red Hat 6.5)

    怎么查看当前的网络状态,这里就不着重描述,用ifconfig命令就可以.我们直接进入主题. red hat系统中的网卡配置在这个目录中:/etc/sysconfig/network-scripts 1 ...

  2. PHP中PSR

    PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准. 文档整理 PSR-0: Autoloading ...

  3. Python3 urllib.parse 常用函数示例

    Python3 urllib.parse 常用函数示例 http://blog.51cto.com/walkerqt/1766670  1.获取url参数. >>> from url ...

  4. scrapy框架 小知识

    持久化 去重规则 深度 cookie start_url 深度和优先级 下载中间件 持久化 步骤 pipeline/items a. 先写pipeline类 class XXXPipeline(obj ...

  5. Part3_lesson1---ARM汇编编程概述

    bootloader以及内核需要使用汇编语言,特别是在初始化的时候!以及在效率要求很高的地方会使用. 汇编程序框架: 其入口在_start处,这个入口需要用一个关键字为.global来声明它是一个全局 ...

  6. 【Django】Django Debug Toolbar调试工具配置

    正在发愁怎么调试Django,就遇到了Django Debug Toolbar这个利器. 先说遇到的问题: 网上也有教程,不过五花八门的,挨个尝试了一遍,也没有成功运行.最后终于找到问题所在: 从开发 ...

  7. ASP.NET’s compilation system

    Compilation in ASP.NET applications First, let’s take a moment to revisit compilation in the context ...

  8. 20、Semantic-UI之数据验证

    20.1 实现数据验证   在很多前端框架中都提供了数据验证的操作,比如jQuery的验证框架等,但是jQuery的验证框架js文件太多:在使用Semantic-UI框架的时候只需要导入semanti ...

  9. java-设计模式汇总整理

    最近,对各种模式做了一个整理,便于后续自用. 1.工厂模式 总结:很好理解,一个接口,2个类实现这个接口,那么可以用“接口 变量=new 接口实现类”的方式调用不同的实现类,调用方式直接使用接口的方法 ...

  10. c3p0-数据库连接池原理

    一直用c3p0很久了,但也没时间或没主动去研究过,直到最近频频在出现一些莫名其妙的问题,觉得还是有必要了解和研究一下. c3p0是什么 c3p0的出现,是为了大大提高应用程序和数据库之间访问效率的. ...