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;
}
思路就是说,还是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;
}
相关文章推荐
- POJ 3368—— Frequent values(频繁出现的数值UVA11235) RMQ
- UVA - 11235 Frequent values 频繁出现的数值(RMQ)
- UVa 11235 频繁出现的数值(RMQ)
- Uva 11235 频繁出现的数值(RMQ-Sparse Table 算法)(训练指南)
- UVA 11235 频繁出现的数值 RMQ
- UVa 11235 频繁出现的数值
- UVa 11235 频繁出现的数值
- 第三章例题8 (频繁出现的数值)RMQ
- UVA - 11235 Frequent values 频繁出现的数值 RMQ+游程编码
- UVA 11235 Frequent values 非递减序列 l r范围内 出现最多的数字次数 RMQ
- Uva 11235 RMQ问题
- Uva 11235 Frequent values (RMQ问题 STable算法的应用)
- UVA 11235 Frequent values(RMQ)
- uva 11235 Frequent Values(游程编码, RMQ)
- UVa 11235 RMQ好题
- UVA 11235 Frequent values(RMQ)
- UVA 11235 Frequent values——RMQ
- UVA 11235 Frequent values(RMQ)
- RMQ算法 以及UVA 11235 Frequent Values(RMQ)
- Frequent Values(UVa 11235) RMQ问题