首页 > 代码库 > HDU1806 Frequent values

HDU1806 Frequent values

题解:

注意数组a是非降序排列。

所以将a数组转化出现次数的数组b

例如 -1 -1 2 3 对应 2 2 1 1

那么每次查询,分为左边,右边和中间三部分,

预处理每个数对应的左右范围.可以用map,也可以用二分。

代码:

//二分处理#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#include<set>#include<vector>using namespace std;using namespace std;#define pb push_back#define mp make_pair#define se second#define fs first#define ll long long#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define ls o<<1#define rs o<<1|1#define SZ(x) ((int)(x).size())#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)typedef pair<int,int> P;const double eps=1e-9;const int maxn=100100;const int N=1e9;const int mod=1e9+7;ll read(){    ll x=0,f=1;char ch=getchar();    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x*f;}//-----------------------------------------------------------------------------int a[maxn],b[maxn],mx[maxn][20];int n,m,k,l,r;map<int,int> Num;void rmq_init(){    for(int i=1;i<=n;i++) mx[i][0]=b[i];    k=(int)(log(n*1.0)/log(2.0));    for(int i=1;i<=k;i++)    for(int j=1;j<=n;j++){        mx[j][i]=mx[j][i-1];        if(j+(1<<(i-1))<=n) mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);    }}int rmq_max(int l,int r){    k=(int)(log((r-l+1.0)*1.0)/log(2.0));    return max(mx[l][k],mx[r-(1<<k)+1][k]);}int bs_left(int l){    int L=1,R=l,Goal=l;    while(L<=R){        int M=(L+R)>>1;        if(a[M]==a[l]){            Goal=M;            R=M-1;        }        else L=M+1;    }    return Goal;}int bs_right(int r){    int L=r,R=n,Goal=r;    while(L<=R){        int M=(L+R)>>1;        if(a[M]==a[r]){            Goal=M;            L=M+1;        }        else R=M-1;            }    return Goal;}int main(){    while(scanf("%d",&n)&&n){        scanf("%d",&m);        Num.clear();        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            Num[a[i]]++;        }        for(int i=1;i<=n;i++) b[i]=Num[a[i]];        rmq_init();        for(int i=1;i<=m;i++){            scanf("%d%d",&l,&r);            if(a[l]==a[r]) printf("%d\n",r-l+1);            else{                int L_max=bs_right(l)-l+1;                int R_max=r-bs_left(r)+1;                int M_max=0;                if(bs_right(l)+1<=bs_left(r)-1) M_max=rmq_max(bs_right(l)+1,bs_left(r)-1);                printf("%d\n",max(max(L_max,R_max),M_max));            }        }    }    return 0;}

 

HDU1806 Frequent values