zoukankan      html  css  js  c++  java
  • POJ 3368:Frequent values RMQ

    Frequent values

    题目链接:

    http://poj.org/problem?id=3368

    题意:

    给出一个非递减序列,求区间内最多的数字的数量

    题解:

    水题,dp[i][j]记录从 i 开始2^j个数中的出现最多的数,合并dp[i][j]和dp[i+(1<<j)][j]得到dp[i][1<<(j+1)]的时候,由于序列是连续的,只要多考虑一个i+(1<<j)-1(即dp[i][j]所能到达的最右端)上得数字在区间内出现的次数就好了。

          

    代码

     
    #include<stdio.h>
    #include<math.h>
    const int N=1e5+2;
    int dp[N][18];
    int mmax(int x,int y)
    {
        return x>y?x:y;
    }
    int mmin(int x,int y)
    {
        return x<y?x:y;
    }
    int l[N*2],r[N*2];
    void Make_Rmq(int n,int p[])
    {
        for(int i=1;i<=n;++i)
        {
            dp[i][0]=p[i];
        }
        for(int j=1;(1<<j)<=n;++j)
        for(int i=1;i+(1<<j)-1<=n;++i)
        {
            int x=dp[i][j-1],y=dp[i+(1<<j-1)][j-1],z=p[i+(1<<j-1)-1];
            int mx=mmin(r[x],i+(1<<j)-1)-mmax(l[x],i)+1;
            dp[i][j]=x;
            if(mmin(r[y],i+(1<<j)-1)-mmax(l[y],i)+1>mx)dp[i][j]=y,mx=mmin(r[y],i+(1<<j)-1)-mmax(l[y],i)+1;
            if(mmin(r[z],i+(1<<j)-1)-mmax(l[z],i)+1>mx)dp[i][j]=z,mx=mmin(r[z],i+(1<<j)-1)-mmax(l[z],i)+1;
        }
    }
    int Get_Rmq(int u,int v,int p[])
    {
        int k=(int)(log(v-u+1.0)/log(2.0));
        int x=dp[u][k],y=dp[v-(1<<k)+1][k],z=p[u+(1<<k)-1];
        int res;
        int mx=mmin(r[x],v)-mmax(l[x],u)+1;
        res=x;
        if(mmin(r[y],v)-mmax(l[y],u)+1>mx)res=y,mx=mmin(r[y],v)-mmax(l[y],u)+1;
        if(mmin(r[z],v)-mmax(l[z],u)+1>mx)res=z,mx=mmin(r[z],v)-mmax(l[z],u)+1;
        return res;
    }
    int w[N];
    void solve()
    {
        int n,Q,x,y;
        w[0]=-1000000000;
        while(~scanf("%d",&n)&&n)
        {
            scanf("%d",&Q);
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&w[i]);
                w[i]+=100000;
                if(w[i]!=w[i-1])l[w[i]]=r[w[i]]=i;
                else ++r[w[i]]; 
            }
            Make_Rmq(n,w);
            while(Q--)
            {
                scanf("%d%d",&x,&y);
                int u=Get_Rmq(x,y,w);
                printf("%d
    ",mmin(r[u],y)-mmax(l[u],x)+1);
            }
        }
    }
    int main()
    {
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    hdu 2222 Keywords Search
    Meet and Greet
    hdu 4673
    hdu 4768
    hdu 4747 Mex
    uva 1513 Movie collection
    uva 12299 RMQ with Shifts
    uva 11732 strcmp() Anyone?
    uva 1401
    hdu 1251 统计难题
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5731007.html
Copyright © 2011-2022 走看看