P2880 [USACO07JAN]平衡的阵容Balanced Lineup

P2880 [USACO07JAN]平衡的阵容Balanced Lineup

RMQ

RMQ模板题

静态求区间最大/最小值

(开了O2还能卡到rank9)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
int wt[50];
template <typename T> inline void output(T x){
    if(!x) {putchar(48); return ;}
    int l=0;
    while(x) wt[++l]=x%10,x/=10;
    while(l) putchar(wt[l--]+48);
}
int n,m,mxd[18][180002],mnd[18][180002],log[180002];
inline int query(int l,int r){ //查询
    int k=log[r-l+1];
    int r1=max(mxd[k][l],mxd[k][r-(1<<k)+1]);
    int r2=min(mnd[k][l],mnd[k][r-(1<<k)+1]);
    return r1-r2;
}
int main(){
    read(n); read(m); int q1,q2; log[0]=-1;
    for(int i=1;i<=n;++i) read(mxd[0][i]),mnd[0][i]=mxd[0][i],log[i]=log[i>>1]+1; //log值预处理
    for(int i=1;(1<<i)<=n;++i)
        for(int j=1;j+(1<<(i-1))<=n;++j){
            mxd[i][j]=max(mxd[i-1][j],mxd[i-1][j+(1<<(i-1))]);
            mnd[i][j]=min(mnd[i-1][j],mnd[i-1][j+(1<<(i-1))]);
        } //普通的RMQ处理
    for(int i=1;i<=m;++i) read(q1),read(q2),output(query(q1,q2)),putchar('\n');
    return 0;
}

 

posted @ 2018-09-23 08:03  kafuuchino  阅读(160)  评论(0编辑  收藏  举报