您的位置:首页 > 其它

RMQ,ST表(频繁出现的数值,UVA 11235)

2016-12-09 16:04 429 查看
有时候递归里面的特殊情况讨论了,然而入口忘记讨论了,就会导致WA。。。

思路就是说,还是ST表嘛,其中ST[i][0]=1,只不过不能直接ST[i][j]=max(ST[i][j-1],ST[i+(1<<j-1)][j-1]),因为有些数值可能跨越了区间,所以就判断一下有没有跨过,如果跨过了就要多考虑这种情况,然后再取其中的最大值。



int ans=1;

然后

if(a[L+(1<<k)-1]==a[R-(1<<k)+1]) ans=min(upper_bound(a,a+n,a[L+(1<<k)-1])-a,R+1)-max(lower_bound(a,a+n,a[L+(1<<k)-1])-a,L);

最后

ans=max(ans,ST[L][k]);

ans=max(ans,ST[R-(1<<k)+1][k]);

然后入口处也别忘了加上这句,我就是这样WA然后搞了很久的。(很常见的一类失误)

代码

#include<bits/stdc++.h>
#define f(i) for(int i=0;i<n;i++)
#define s(i) scanf("%d",&i)
#define p(i) printf("%d\n",i)
#define ss(a) for(int i=0;i<n;i++) scanf("%d",a+i)
#define maxn 100010
using namespace std;

int n,q;
int a[maxn];
int ST[maxn][20];

int min(int a,int b)
{
return a<b?a:b;
}

int max(int a,int b)
{
return a>b?a:b;
}

void st()
{
f(i) ST[i][0]=1;
for(int j=1;(1<<j)<=n;j++)
for(int i=0;i+(1<<j)-1<n;i++)
{
if(a[i+(1<<(j-1))-1]==a[i+(1<<j)-(1<<(j-1))])
ST[i][j]=min(upper_bound(a,a+n,a[i+(1<<(j-1))-1])-a,i+(1<<j))-max(lower_bound(a,a+n,a[i+(1<<(j-1))-1])-a,i);
else
ST[i][j]=1;
ST[i][j]=max(ST[i][j],ST[i][j-1]);
ST[i][j]=max(ST[i][j],ST[i+(1<<(j-1))][j-1]);
}
}

int qry(int L,int R)
{

int k=0;
while(1<<(k+1)<=R-L+1) k++;
int ans=1;
if(a[L+(1<<k)-1]==a[R-(1<<k)+1]) ans=min(upper_bound(a,a+n,a[L+(1<<k)-1])-a,R+1)-max(lower_bound(a,a+n,a[L+(1<<k)-1])-a,L);
ans=max(ans,ST[L][k]);
ans=max(ans,ST[R-(1<<k)+1][k]);
return ans;
}

int main()
{
while(s(n)==1&&n)
{
s(q);
ss(a);
st();
int L,R;
while(q--)
{
s(L);
s(R);
p(qry(L-1,R-1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: