Frequent values UVA - 11235 rmq

也不是说麻烦,,看来还是我的码力太差了,敲的老是要看标称。。

而且有些细节没考虑好。、、

其实这就是简单的rmq,但我的代码还是错了。。


#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define INF 10000000000
#define bug1 cout<<"bug1\n";
#define inf 0x3f3f3f3f
const int N=1e6+5;
int n,q;
int A[N];
int cnt[N],id[N];
int d[N][20];
//int left[N],right[N];
int le[10000],ri[10000];
void init_rmq(int n,int *A){
    rep(i,0,n)d[i][0]=A[i];
    for(int j=1;(1<<j)<=n;++j){
        for(int i=0;i+(1<<j)-1<n;++i){
            d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
        }
    }
}
int rmq(int l,int r){
    int k=0;
    while((1<<(k+1))<=r-l+1)k++;
    return max(d[l][k],d[r-(1<<k)+1][k]);
}
int main(){
    while(~sf("%d%d",&n,&q)&&n){
        mem(cnt,0);
        mem(d,0);
        mem(id,0);
        rep(i,0,n-1)sf("%d",&A[i]);
        int start=0;
        int tol=0;
        A[n]=INF;
        rep(i,0,n){
            if(i==0||A[i]>A[i-1]){
                if(i>0){
                    cnt[tol++]=i-start;
                    for(int j=start;j<=i-1;++j){
                        id[j]=tol-1;
                        le[j]=start;ri[j]=i-1;
                    }
                }
                start=i;
            }
        }tol--;
        init_rmq(tol,cnt);
        rep(i,1,q){
            int l,r;sf("%d%d",&l,&r);
            l--;r--;
            if(id[l]==id[r])pf("%d\n",r-l+1);
            else {
                int ans=max(ri[l]-l+1,r-le[r]+1);
                if(id[l]+1<id[r])ans=max(ans,rmq(id[l]+1,id[r]-1));
                pf("%d\n",ans);
            }
        }
    }
}

// UVa11235 Frequent Values
// Rujia Liu
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn = 100000 + 5;
const int maxlog = 20;

// 区间最*大*值
struct RMQ {
  int d[maxn][maxlog];
  void init(const vector<int>& A) {
    int n = A.size();
    for(int i = 0; i < n; i++) d[i][0] = A[i];
    for(int j = 1; (1<<j) <= n; j++)
      for(int i = 0; i + (1<<j) - 1 < n; i++)
        d[i][j] = max(d[i][j-1], d[i + (1<<(j-1))][j-1]);
  }

  int query(int L, int R) {
    int k = 0;
    while((1<<(k+1)) <= R-L+1) k++; // 如果2^(k+1)<=R-L+1,那么k还可以加1
    return max(d[L][k], d[R-(1<<k)+1][k]);
  }
};						

int a[maxn], num[maxn], left[maxn], right[maxn];
RMQ rmq;
int main() {
  int n, q;
  while(scanf("%d%d", &n, &q) == 2) {
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    a[n] = a[n-1] + 1; // 哨兵
    int start = -1;
    vector<int> count;
    for(int i = 0; i <= n; i++) {
      if(i == 0 || a[i] > a[i-1]) { // 新段开始
        if(i > 0) {
          count.push_back(i - start);
          for(int j = start; j < i; j++) {
            num[j] = count.size() - 1; left[j] = start; right[j] = i-1;
          }
        }
        start = i;
      }
    }
    rmq.init(count);
    while(q--) {
      int L, R, ans;
      scanf("%d%d", &L, &R); L--; R--;
      if(num[L] == num[R]) ans = R-L+1;
      else {
        ans = max(R-left[R]+1, right[L]-L+1);
        if(num[L]+1 < num[R]) ans = max(ans, rmq.query(num[L]+1, num[R]-1));
      }
      printf("%d\n", ans);
    }
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值