关闭

HDU 3530 Subsequence(STL)

标签: HDUalgorithm
470人阅读 评论(0) 收藏 举报
分类:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3530

题意:给定一个长度为n的数组,n最大为10万,让你求最长区间长度使这个区间的最大值减去最小值在m和k之间(包括m和k)

开始以为是什么树状数组什么的,后来看见时间给的是1s,就往O(n)的方向去想

用两个set维护当前区间的最大值和最小值,如果最大值与最小值差比k大,如果end继续向后走一定不会符合条件,那么让begin向前走

一直走到最大值减去最小值小于等于k。

end++一次

总之就是区间一定是连续的,枚举每一个位置为末尾的答案

由于每个点最多进set一次出set一次,时间复杂度O(n)

注意为了防止元素一样值不好删除,附带位置,这样能唯一确定set中的某个元素

#include <string.h>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <set>
using namespace std;
const int maxn = 110000;
struct point{
    int value;
    int pos;
    point(int v=0,int p=0):value(v),pos(p){}
    bool operator < (const point &a) const{
        if(value==a.value) return pos<a.pos;
        return value > a.value;
    }
    bool operator == (const point &a) const{
        return value==a.value && pos==a.pos;
    }
};
struct node{
    int value;
    int pos;
    node(int v=0,int p=0):value(v),pos(p){}
    bool operator < (const node &a) const {
        if(value==a.value) return pos<a.pos;
        return value < a.value;
    }
    bool operator == (const node &a) const{
        return value==a.value && pos==a.pos;
    }
};
int rec[maxn],n,m,k;
set<point> se_max;
set<node> se_small;
int main(){
    int i,j,begin,end,ans,t;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF){
        se_max.clear();
        se_small.clear();
        for(i=0;i<n;i++) scanf("%d",&rec[i]);
        begin=0;
        end=1;
        ans=0;
        se_small.insert(node(rec[0],0));
        se_max.insert(point(rec[0],0));
        while(end<n){
            while(se_max.begin()->value-se_small.begin()->value > k){
                se_max.erase(point(rec[begin],begin));
                se_small.erase(node(rec[begin],begin));
                begin++;
            }
            t=se_max.begin()->value-se_small.begin()->value;
            if(t>=m && t<=k) ans=max(ans,end-begin);
            se_max.insert(point(rec[end],end));
            se_small.insert(node(rec[end],end));
            t=se_max.begin()->value-se_small.begin()->value;
            if(t>=m && t<=k) ans=max(ans,end-begin+1);
            end++;
        }
        t=se_max.begin()->value-se_small.begin()->value;
        if(t>=m && t<=k) ans=max(ans,end-begin);
        printf("%d\n",ans);
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:131076次
    • 积分:3448
    • 等级:
    • 排名:第10045名
    • 原创:221篇
    • 转载:0篇
    • 译文:0篇
    • 评论:8条
    最新评论