• [RMQ] [线段树] POJ 3368 Frequent Values


    一句话,多次查询区间的众数的次数

    注意多组数据!!!!

    RMQ方法:

    预处理 i 及其之前相同的数的个数

    再倒着预处理出 i 到不是与 a[i] 相等的位置之前的一个位置, 查询时分成相同的一段和不同的一段 (RMQ)

    但是要注意 to[i] 大于查询范围的情况, 以及RMQ时 x < y 的情况!!

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #include<string>
    #include<iomanip>
    #include<ctime>
    #include<climits>
    #include<cctype>
    #include<algorithm>
    #ifdef WIN32
    #define AUTO "%I64d"
    #else
    #define AUTO "%lld"
    #endif
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=100005;
    const int maxd=20;
    int n,q;
    int a[maxn];
    int sum[maxn];
    int to[maxn];
    inline bool init()
    {
        if(!~scanf("%d%d",&n,&q) || !n) return false;
        for(int i=1;i<=n;i++) scanf("%d",a+i);
        sum[1]=1;
        for(int i=2;i<=n;i++)
            if(a[i-1]^a[i]) sum[i]=1;
            else sum[i]=sum[i-1]+1;
        to[n]=n;
        for(int i=n-1;i;i--)
            to[i] = a[i]^a[i+1]? i : to[i+1];
        return true;
    }
    int dp[maxn][maxd];
    void ST()
    {
        for(int i=1;i<=n;i++) dp[i][0] = sum[i];
        int k=0;
        while( (1<<k+1) <= n ) k++;
        for(int j=1;j<=k;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                dp[i][j] = max( dp[i][j-1] , dp[i+(1<<j-1)][j-1] ); // j-1 moved !!!
    }
    inline int RMQ(int x,int y)
    {
        if (x>y) return -INF; // INF here to make the case extinct!!
        int k=0;
        while( (1<<k+1) <= (y-x+1) ) k++;
        return max(dp[x][k] , dp[y-(1<<k)+1][k]);
    }
    int main()
    {
        freopen("fre.in","r",stdin);
        freopen("fre.out","w",stdout);
        while(init())
        {
            ST();
            for(int i=1;i<=q;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%d
    ",max(sum[min(to[x],y)]-sum[x]+1 , RMQ(to[x]+1,y)));
            }
        }
        return 0;
    }
    View Code

    线段树方法:

    不急,懒得写了。。

  • 相关阅读:
    WEBSHELL跳板REDUH使用说明
    lcx.exe内网转发命令教程 + LCX免杀下载
    程序只启动一个实例的几种方法
    VS2010中遇到_WIN32_WINNT not defined
    VC编译错误: Nafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12已经在dllmain.obj 中定义
    python(31) enumerate 的用法
    利用余弦定理计算文本的相似度
    Linux命令(24) :sort
    python(30) 获取网页返回的状态码,状态码对应问题查询
    python(29)强大的zip函数
  • 原文地址:https://www.cnblogs.com/ourfutr2330/p/5668354.html
Copyright © 2020-2023  润新知