「一本通 4.2 例 3」与众不同
这道题预处理有点烦
因为查询的时候分两块
一个st表
一个贪心直接加减
二分找中间值
#include<bits/stdc++.h> #define re return #define ll long long #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=1e6+5,maxm=1e6+5; int Log[maxn],f[maxn][25],st[maxn],last[maxm<<1]; int n,m; inline int query(int x,int y) { int k=Log[y-x+1]; re max(f[x][k],f[y-(1<<k)+1][k]); } int main() { // freopen("in.txt","r",stdin); int x,y; rd(n),rd(m); Log[0]=-1; inc(i,1,n) { rd(x); st[i]=max(st[i-1],last[x+maxm]+1); f[i][0]=i-st[i]+1; Log[i]=Log[i>>1]+1; last[x+maxm]=i; } for(int j=1;j<=Log[n];++j) for(int i=1;i+(1<<j)-1<=n;++i) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); inc(i,1,m) { rd(x),rd(y); ++x;++y; int l=x,r=y,ans=0; while(l<=r) { int mid=(l+r)>>1; if(st[mid]<x)l=mid+1; else r=mid-1; } if(l>x)ans=l-x; if(l<=y) ans=max(ans,query(l,y)); printf("%d\n",ans); } re 0; }