`

poj 3368

 
阅读更多

题意:一个具有n(1~100000)个点的序列,从大到小排序,有一些点的大小是相等的,问区间[a,b]上,相等大小的点最多是几个。

 

思路:线段树+离散化。离散的运用:将连续的相等的一个区间的点集,聚集为线段树的一个节点,并且在这个节点上有信息能体现出这个区间的性质。

 代码如下:

#include<iostream>
using namespace std;
const int Max = 100050;

struct
{
    int l, r, max;
}node[3*Max];

struct
{
    int sta, end;
}seg[Max];


int num[Max], hash[Max];
int max(int a, int b)
{
    return a > b ? a : b;
}

void BuildTree(int left, int right, int u)
{            //  建树。
    node[u].l = left;
    node[u].r = right;
    if(left == right)
	{
        int k = left;
        node[u].max = seg[k].end - seg[k].sta + 1;     //  max保存这个点集的点的数量。
        return;
    }
    int mid = (left+right)>>1;
    BuildTree(left, mid, u<<1);
    BuildTree(mid+1, right, (u<<1)+1);
    node[u].max = max(node[u<<1].max, node[(u<<1)+1].max);
}

int query(int left, int right, int u)
{                 //  查询。
    if(node[u].l == left && node[u].r == right)
        return node[u].max;
    if(right <= node[u<<1].r)
        return query(left, right, u<<1);
    if(left >= node[(u<<1)+1].l)
        return query(left, right, (u<<1)+1);
    int a = query(left, node[u<<1].r, u<<1);
    int b = query(node[(u<<1)+1].l, right, (u<<1)+1);
    return max(a, b);
}

int main()
{
    int n, m, i;
    while(scanf("%d", &n) && n)
	{
        scanf("%d", &m);
        for(i = 1; i <= n; i ++)
            scanf("%d", &num[i]);
        int k = 0, pre = 999999;
        for(i = 1; i <= n; i ++)
		{      //  离散化,将点的序列离散化为一个个的点集。
            if(num[i] != pre)
			{
                pre = num[i];
                k++;
                seg[k].sta = i;
                seg[k].end = i;
            }
            else seg[k].end = i;
            hash[i] = k;               //  hash保存序列上第i个点,对应的点集的下标。
        }
        BuildTree(1, k, 1);
        while(m--)
		{
            int a, b, pos1, pos2;
            scanf("%d%d", &a, &b);
            pos1 = hash[a];
            pos2 = hash[b];            //  *.如下,好的主函数操作能很大程度上简化线段树的复杂度。
            if(pos1 == pos2)           //  情况1:[a,b]为一个点集。
                printf("%d\n", b-a+1);
            else
			{                      //  情况2,3:[a,b]包含多个点集。
                int n1 = seg[pos1].end - a + 1;
                int n2 = 0;
                int n3 = b - seg[pos2].sta + 1;
                if(pos2 - pos1 > 1)    //  情况3:[a,b]包含3个以上点集,中间点集最大值用到线段树。
                    n2 = query(pos1+1, pos2-1, 1); 
                printf("%d\n", max(max(n1, n3), n2));
            }
        }
    }
    return 0;
}

 

 

分享到:
评论

相关推荐

    Frequent Values(poj 3368) C

    在本题目"Frequent Values (poj 3368)"中,我们需要解决的是一个与数据处理和算法相关的编程问题。该题目是广东工业大学《算法和高级数据结构教程课程设计》的一部分,采用C语言进行实现。下面我们将深入探讨这个...

    poj题目分类

    * RMQ:例如 poj3264、poj3368。 * 并查集的高级应用:例如 poj1703、poj2492。 * KMP 算法:例如 poj1961、poj2406。 4. 搜索: * 最优化剪枝和可行性剪枝。 * 搜索的技巧和优化:例如 poj3411、poj1724。 *...

    poj训练计划.doc

    - RMQ(区间查询):如`poj3264, poj3368`。 - 并查集的高级应用:如`poj1703, poj2492`。 - **搜索** - 最优化剪枝和可行性剪枝:如`poj3411, poj1724`。 - **动态规划** - 复杂的动态规划:如`poj1191, poj...

    acm训练计划(poj的题)

    - (poj3264, poj3368):如何快速获取指定区间内的最大值。 5. **后缀数组/后缀自动机**: - (poj1703, 2492):用于文本检索的强大工具。 6. **KMP算法**: - (poj1961, poj2406):高效的字符串匹配算法。 ### ...

    经典 的POJ 分类

    - POJ 3264、POJ 3368:树状数组的构造与更新。 #### 字符串匹配 - **题目示例**: - POJ 1961、POJ 2406:KMP算法的应用。 ### 其他问题 #### 贪心算法 - **题目示例**: - POJ 3411、POJ 1724:贪心策略的...

    acm新手刷题攻略之poj

    - 推荐题目:[poj3264](https://vjudge.net/problem/POJ-3264)、[poj3368](https://vjudge.net/problem/POJ-3368) - 区间查询问题通常涉及线段树或树状数组等数据结构。 5. **字符串匹配** - 推荐题目:[poj1961...

    ACM-POJ 算法训练指南

    4. **区间查询**:如RMQ问题(poj3264, poj3368)。 5. **字符串匹配**:如KMP算法(poj1961, poj2406)。 ### 十三、进阶算法 1. **组合优化**:如割平面法、分支定界法等(poj3411, poj1724)。 2. **近似算法**...

    ACMer需要掌握的算法讲解 (2).docx

    * RMQ:POJ3264、POJ3368 * 并查集的高级应用:POJ1703、POJ2492 * KMP算法:POJ1961、POJ2406 * 左偏树(可合并堆) 四、搜索 * 最优化剪枝和可行性剪枝 * 较为复杂的动态规划:POJ1191、POJ1054、POJ3280、POJ...

    ACM常用算法及其相应的练习题.docx

    ACM常用算法及其相应的练习题 ... + poj3264, poj3368 * 并查集的高级应用 + poj1703, poj2492 * KMP算法 + poj1961, poj2406 四、搜索 * 最优化剪枝和可行性剪枝 * 搜索的技巧和优化 + poj3411, poj1724

    ACMer需要掌握的算法讲解.docx

    1. RMQ(poj3264, poj3368) 2. 并查集的高级应用(poj1703, poj2492) 3. KMP 算法(poj1961, poj2406) 4. 左偏树(可合并堆) 四、搜索 1. 最优化剪枝和可行性剪枝 2. 较为复杂的动态规划(如动态规划解特别的...

    ACM 题型

    - 示例题目:poj3264, poj3368 - **后缀数组** - 示例题目:poj1703, poj2492 - **KMP算法** - 示例题目:poj1961, poj2406 #### 高级动态规划 1. **矩阵乘法** - 示例题目:poj1191, poj1054, poj3280, poj...

    算法训练方案详解

    - **示例题目**: POJ 3267, POJ 1836, POJ 1260, POJ 2533, POJ 3176, POJ 1080, POJ 1159 - **注意事项**: 理解每种模型的状态定义和转移方程。 #### 六、数学 **1. 组合数学** - **定义**: 研究组合结构的...

    ACM算法总结--最新总结的ACM算法

    4. **RMQ(Range Minimum Query)**(如poj3264, poj3368):快速查询区间内的最小值,适用于数据压缩、图像处理等领域。 5. **后缀树/后缀数组**(如poj1703, 2492):用于字符串的高效处理,适用于文本索引、生物...

    LCA与RMQ相关题解1

    在POJ3368中,需要找出非降序序列中同一数值的数量。这里同样可以利用RMQ思想,不过在初始化动态规划(DP)时,DP[i]不仅存储信息,还记录了有多少个相同的数字。这样在查询时,通过RMQ可以快速找到两个数之间的相同...

    线段树题目

    - **POJ 3368**:要求求解有序数组区间出现频率最多次数。在线段树中需要额外维护区间内的最大频率信息。 - **ZOJ 2859**:涉及到二维线段树的应用,需要求解矩阵的部分最大值。这通常需要在二维空间中构建线段树,...

    广工《算法和高级数据结构教程课程设计》

    一、Frequent Values (poj 3368) 题目分析与解法 1. 问题描述:该问题要求设计一个程序,用于求解一个固定序列中任意区间内出现频次最高的数。序列中的数已经按从大到小排序,且给定了若干个查询,每个查询都会指定...

    poj pku 解题报告

    1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1011 1012 1013 1014 ...3368 3372 3386 3400 3421 3424 3425 3427 3428 3438 3452 3468 3486 3517 3561 3585 3589 3602 3612 3614 3615 3616 3617 3618 3619 3620 ...

    树状数组(Binary Indexed Tree)

    2. **洛谷P3368:区间修改,单点查询** - **题意**:给定一个数组,支持两种操作:一是修改某个区间内所有元素的值;二是查询某个位置的值。 - **解法**:除了使用普通的树状数组外,还需要额外维护一个差分数组来...

Global site tag (gtag.js) - Google Analytics