一、题面

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. XSS的原理分析与解剖:第三章(技巧篇)【转】

    0×01 前言: 关于前两节url: 第一章:http://www.freebuf.com/articles/web/40520.html 第二章:http://www.freebuf.com/art ...

  2. C# WebService中任务处理线程创建子线程后

    protected void WriteLog(string message) { lock (lockObject) { var file = System.IO.File.AppendText(& ...

  3. CMDB和运维自动化

    IT运维,指的是对已经搭建好的网络,软件,硬件进行维护.运维领域也是有细分的,有硬件运维和软件运维 硬件运维主要包括对基础设施的运维,比如机房的设备,主机的硬盘,内存这些物理设备的维护 软件运维主要包 ...

  4. cmd 中连接mysql时报'mysql'不是内部或外部命令,也不是可运行的程序或批处理文件,该怎么办?

    假设安装的mysql目录是D:\MySQL\MySQL_Server_5.5\第一种方法:如果你打开cmd后直接输入mysql是不行的,需要配置mysql的环境变量,那么就在环境变量中增加D:\MyS ...

  5. jquery 常用工具方法

    inArray(value, array [, fromIndex ])方法类似于原生javascript的indexOf()方法,没有找到匹配元素时它返回-1.如果数组第一个元素匹配参数,那么$.i ...

  6. CodeForces 427A Police Recruits (水题)

    题意:给定 n 个数,有正数和-1, -1表示罪犯,正数表示招了几个警察,一个警察只能看一个罪犯,并且要按顺序,问你有多少罪犯逃脱. 析:很简单么,从开始扫到最后,把是正数就加上,是-1判断剩余警察大 ...

  7. JavaScript语言精粹 笔记05 正则表达式

    正则表达式 正则表达式以方法的形式被用于对字符串中的信息进行查找.替换画图提取操作.可处理正则表达式的方法有:regexp.exec, regexp.test,string.match, string ...

  8. 团体程序设计天梯赛L1-022 奇偶分家 2017-03-22 17:48 81人阅读 评论(0) 收藏

    L1-022. 奇偶分家 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定N个正整数,请统计奇数和偶数各有多少个? 输入格式 ...

  9. opencv—读取一张图片并滤波

    #include <opencv2\opencv.hpp> #include <iostream> #include <string> using namespac ...

  10. Android-广播概念

    Android中的消息机制 1.Handler+Message消息机制,是用于子线程与主线程的通讯: 2.广播+广播接收者也是消息机制,是重量级别的,四大组件之一,需要激活组件,是用于组件和组件之间通 ...