Uva 11235 (RMQ)

两个代码都是WA

RMQ:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 100009
#define INF -0x7f7f7f
int a[MAX],num[MAX],value[MAX],Count[MAX],left[MAX],right[MAX];
int dp[100009][100];
void RMQ_init(int cnt){
    for(int i=0;i<cnt;i++){
        dp[i][0]=Count[i];
    }
    for(int i=1;(1<<i)<=cnt;i++){
        for(int j=0;j+(1<<i)-1<cnt;j++){
            dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
        }
    }
}
int RMQ(int L,int R){
    int k=0;
    while((1<<(k+1))<=(R-L+1)) k++;
    return max(dp[L][k],dp[R-(1<<k)+1][k]);
}
int main(){
    int n,q;
    while(~scanf("%d",&n),n){
        scanf("%d",&q);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        memset(Count,0,sizeof(Count));
        memset(value,0,sizeof(value));
        int cnt=0;
        value[cnt]=a[0];
        Count[cnt]=1;
        left[cnt]=0;
        num[0]=cnt;
        for(int i=1;i<n;i++){
            if(a[i]==value[cnt]){
                Count[cnt]++;
                num[i]=cnt;
            }else{
                right[cnt]=i-1;
                value[++cnt]=a[i];
                left[cnt]=i;
                num[i]=cnt;
                Count[cnt]++;
            }
        }
        right[cnt]=n-1;
        RMQ_init(cnt+1);
        int L,R,ans,s,e;
        for(int i=0;i<q;i++){
            scanf("%d %d",&s,&e);
            ans=INF;
            L=num[s-1];
            R=num[e-1];
            int tmp=right[L]-(s-1)+1;
            ans=tmp;
            if(L+1<=R-1)tmp=RMQ(L+1,R-1);
            if(ans<tmp) ans=tmp;
            tmp=(e-1)-left[R]+1;
            if(ans<tmp) ans=tmp;
            printf("%d\n",ans);
        }
    }
return 0;
}

线段树:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAX 100009
#define INF -0xffffff0
int a[MAX],num[MAX],value[MAX],Count[MAX],left[MAX],right[MAX];
int maxV;
struct Node{
	int maxV;
	int L;
	int R;
	int mid(){
		return (L+R)/2;
	}
}tree[MAX*4];
void build(int root, int s,int e){
	tree[root].L=s;
	tree[root].R=e;
	tree[root].maxV=-INF;
	if(tree[root].L!=tree[root].R){
		build(root*2,s,tree[root].mid());
		build(root*2+1,tree[root].mid()+1,e);
	}
}
void insert(int root, int pos, int val){
	if(tree[root].L==tree[root].R){
		tree[root].maxV=val;
		return;
	}
	tree[root].maxV=max(tree[root].maxV,val);
	if(pos<=tree[root].mid()){
		insert(root*2, pos, val);
	}else{
		insert(root*2+1,pos,val);
	}
}
void query(int root, int s, int e){
	if(tree[root].L==s&&tree[root].R==e){
		maxV=max(tree[root].maxV,maxV);
		return ;
	}
	if(e<=tree[root].mid()){
		query(root*2,s,e);
	}else if(s>tree[root].mid()){
		query(root*2+1,s,e);
	}else{
		query(root*2,s,tree[root].mid());
		query(root*2+1,tree[root].mid()+1,e);
	}
}
int main(){
    int n,q;
    while(~scanf("%d",&n),n){
        scanf("%d",&q);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        memset(Count,0,sizeof(Count));
        memset(value,0,sizeof(value));
        int cnt=0;
        value[cnt]=a[0];
        Count[cnt]=1;
        left[cnt]=0;
        num[0]=cnt;
        for(int i=1;i<n;i++){
            if(a[i]==value[cnt]){
                Count[cnt]++;
                num[i]=cnt;
            }else{
                right[cnt]=i-1;
                value[++cnt]=a[i];
                left[cnt]=i;
                num[i]=cnt;
                Count[cnt]++;
            }
        }
        right[cnt]=n-1;
        build(1,0,cnt);
        for(int i=0;i<=cnt;i++){
            insert(1,i,Count[i]);
        }
        int L,R,ans,s,e;
        for(int i=0;i<q;i++){
            scanf("%d %d",&s,&e);
            if(s>e) swap(e,s);
            s--;
            e--;
            L=num[s];
            R=num[e];
            ans=max(right[L]-s+1,e-left[R]+1);
            L++;
            R--;
            if(L<=R){
                maxV=INF;
                query(1,L,R);
                ans=max(ans,maxV);
            }
            printf("%d\n",ans);
        }
    }
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值