POJ 3419 Difference Is Beautiful

时间:2023-03-08 17:04:37
POJ 3419 Difference Is Beautiful

先处理出每一个i位置向左最远能到达的位置L[i]。每一次询问,要找到L,R区间中的p位置,p位置左边的L[i]都是小于L的,p位置开始,到R位置,L[i]都大于等于L,对于前者,最大值为p-L,后者求一个区间最大值即可。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
inline int read()
{
char c = getchar(); while(!isdigit(c)) c = getchar();
int x = ;
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
return x;
} const int maxn=+;
int n,a[maxn],b[maxn],c[maxn],q,L[maxn];
int dp[maxn][],f[maxn]; void RMQ_init()
{
for(int i=;i<n;i++) dp[i][]=f[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<n;i++)
dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
} int RMQ(int L,int R)
{
int k=;
while((<<(k+))<=R-L+) k++;
return max(dp[L][k],dp[R-(<<k)+][k]);
} int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b, b + n); int sz = unique(b, b + n) - b;
for(int i=;i<n;i++) a[i]=lower_bound(b, b + sz, a[i])-b+;
memset(c,-,sizeof c);
for(int i=;i<n;i++)
{
if(i==) L[]=,c[a[i]]=;
else L[i]=max(L[i-],c[a[i]]+),c[a[i]]=i;
}
for(int i=;i<n;i++) f[i]=i-L[i]+;
RMQ_init();
for(int i=;i<=q;i++)
{
int LL,RR; scanf("%d%d",&LL,&RR);
int l=LL,r=RR,p=-;
while(l<=r)
{
int mid=(l+r)/;
if(L[mid]<LL) l=mid+,p=mid;
else r=mid-;
}
int ans;
if(p==-) ans=RMQ(LL,RR);
else if(p==RR) ans=RR-LL+;
else ans=max(p-LL+,RMQ(p+,RR));
printf("%d\n",ans);
}
return ;
}