POJ-3368 Frequent values 【ST表】

Frequent values

题目链接:https://vjudge.net/problem/POJ-3368

思路

我的代码有两个预处理:
第一个init: 将数组中的相等的元素,用首项是1,公差是1的等差数列表示,放在cnt[]中 然后用R[]数组,来表示某个元素所在段的下一段的起点 这个初始化,可以把我代码中的cnt[]和R[]打印出来,一看就能明白
预处理init_st:
就是对于cnt这个数组,求区间最大值。
处理的时候,有可能L所在段是被切断的,所以第一段可能不完整,但是在一段内cnt[]是一个前缀和,所以可以通过上面R[]定位到下一段的开始,就可以用前缀和高出这一段的元素个数,然后l = R[l]就把l移动到下一段的开始,然后直接查ST表就得出了[l,r]区间cnt[]中的最大值

代码

#include <iostream>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <cstring>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 1e5+10;
using namespace std;

int N,Q;
int arr[maxn];
int cnt[maxn],R[maxn];
int st[maxn][30];

inline void read(int &x){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    x = s*w;
}

void init_st(){
    for(int i = 1;i<=N;i++) st[i][0] = cnt[i];
    int len = log(N)/log(2);
    for(int j = 1;j<=len;j++){
        for(int i = 1;i<=N-(1<<j)+1;i++){
            st[i][j] = max(st[i][j-1],st[i + (1<<(j-1))][j-1]);
        }
    }
}
void init(){
    arr[0] = -2e9;
    for(int i = 1;i<=N;i++){
        if(arr[i] != arr[i-1]) cnt[i] = 1;
        else cnt[i] = cnt[i-1] + 1;
    }
    int last = N+1;
    for(int i = N;i>=1;i--){
        R[i] = last;
        if(cnt[i] == 1) last = i;
    }
}
int main(){
    while(scanf("%d",&N)){
        if(N == 0) break;read(Q);
        for(int i = 1;i<=N;i++) read(arr[i]);
        init();
        init_st();
        while(Q--){
            int l,r;read(l),read(r);
            int ans = cnt[min(R[l]-1,r)] - cnt[l] + 1;
            l = R[l];
            if(l<=r){
                int len = log(r-l+1)/log(2);
                ans = max(ans,max(st[l][len],st[r-(1<<len)+1][len]));
            }
            printf("%d\n",ans);
        }

    }

    return 0;
}
Ryuichi的算法分享 文章被收录于专栏

分享我的一些算法题解,致力于把题解做好,部分题解可能会采用视频的形式来讲解。

全部评论

相关推荐

Noel_:中石油是这样的 哥们侥幸混进免笔试名单 一看给我吓尿了
点赞 评论 收藏
分享
和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务