前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10121. 「一本通 4.2 例 3」与众不同

10121. 「一本通 4.2 例 3」与众不同

作者头像
yzxoi
发布2022-09-19 12:06:31
3240
发布2022-09-19 12:06:31
举报
文章被收录于专栏:OI

10121. 「一本通 4.2 例 3」与众不同

题意

定义完美序列:一段连续的序列满足序列中的数互不相同。 想知道区间 [L,R] 之间最长的完美序列长度。

思路

个数结尾的最长完美序列的起始位置。

st[i]=max(st[i-1],las[a[i]]+1)

设个数结尾的最长完美序列的长度

f[i]=i-st[i]+1

  • 左边一部分的st值不在区间内,即<l_i
  • 右边一部分的st值不在区间内,即\ge l_i

_i,可得:

st[l_i…mid_i-1]<l_i
st[mid_i…r_i]\ge l_i

那么整个区间

  • 左边:很显然为mid_i-l_i
  • 右边:MAX(m_i…r_i)

所以右边的长度要使用ST表,即RMQ来求。 整个问题的时间复杂度:

O((M+N) \times logN)
代码语言:javascript
复制
#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cstring>
#include<cmath>
#define ll long long
const int N=2e5+5,M=1e6;
using namespace std;
inline ll read(){
    char ch=getchar();ll res=0,f=1;
    while(ch<'0'ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
    return res*f;
}
inline void write(ll zx){
    if(zx<0) zx=-zx,putchar('-');
    if(zx<10) putchar(zx+'0');
    else{
        write(zx/10);
        putchar(zx%10+'0');
    }
}
ll n,m,f[N][20],st[N],las[M<<1];
void ST(){
    for(ll j=1;(1<<j)<=n;j++){
        for(ll i=1;i+(1<<j)-1<=n;i++){
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        }
    }
}
ll RMQ(ll l,ll r){
    ll k=0;
    while((1<<(k+1))<=r-l+1) k++;
    return max(f[l][k],f[r-(1<<k)+1][k]);
}
ll find(ll l,ll r){
    if(st[l]==l) return l;
    if(st[r]<l) return r+1;
    int L=l,R=r;
    while(L<=R){
        int m=L+R>>1;
        if(st[m]<l) L=m+1;
        else R=m-1;
    }
    return L;
}
int main(){
    n=read();m=read();
    for(ll i=1;i<=n;i++){
        int x=read();
        st[i]=max(st[i-1],las[x+M]+1);
        f[i][0]=i-st[i]+1;
        las[x+M]=i;
    }
    ST();
    for(ll i=1;i<=m;i++){
        ll L,R;
        L=read();R=read();L++;R++;
        ll mid=find(L,R),ans=0,tmp;
        if(mid>L) ans=mid-L;
        if(mid<=R){
            tmp=RMQ(mid,R);
            ans=max(ans,tmp);
        }
        write(ans);putchar('\n');
    }
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 10121. 「一本通 4.2 例 3」与众不同
    • 题意
      • 思路
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档