zoukankan      html  css  js  c++  java
  • poj 3368 Frequent values

    Description

    You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

    Input

    The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the 
    query.

    The last test case is followed by a line containing a single 0.

    Output

    For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.

    Sample Input

    10 3
    -1 -1 1 1 1 1 3 10 10 10
    2 3
    1 10
    5 10
    0

    Sample Output

    1
    4
    3

    好复杂的一道线段树+二分的题目,
    首先把每一个不同的数看作一个点,建立线段树,然后再加上二分的处理
    #include<map>
    #include<set>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define  inf 0x0f0f0f0f
    using namespace std;
    
    const int maxn=100000+10;
    
    struct node
    {
        int left,right,mmax;
    }tree[maxn*4];
    int a[maxn],b[maxn],c[maxn];
    
    void buildtree(int c,int x,int y)
    {
        tree[c].left=x;
        tree[c].right=y;
        if (x==y)
        {
            tree[c].mmax=a[x];
            return;
        }
        int mid=x+(y-x)/2;
        buildtree(c*2,x,mid);
        buildtree(c*2+1,mid+1,y);
        tree[c].mmax=max(tree[c*2].mmax,tree[c*2+1].mmax);
    }
    
    int get_max(int c,int x,int y)
    {
        if (tree[c].left==x && tree[c].right==y) return tree[c].mmax;
        int mid=tree[c].left+(tree[c].right-tree[c].left)/2;
        if (y<=mid) return get_max(c*2,x,y);
        else if (x>mid) return get_max(c*2+1,x,y);
        else return max(get_max(c*2,x,mid),get_max(c*2+1,mid+1,y));
    }
    
    int unique(int n)
    {
        int cut=1,j=1;
        int ans=1;
        c[1]=b[1];
        for(int i=2;i<=n;i++)
        {
            if (b[i]==c[j]) ans++;
            else
            {
                a[j]=ans;
                ans=1;
                c[++j]=b[i];
            }
        }
        a[j]=ans;
        return j;
    }
    
    int find(int x,int y,int v)
    {
        while(x<y)
        {
            int m=x+(y-x)/2;
            if (c[m]>=v) y=m;
            else x=m+1;
        }
        return x;
    }
    
    int bfind_down(int x,int y,int v)
    {
        while(x<y)
        {
            int m=x+(y-x)/2;
            if (b[m]>=v) y=m;
            else x=m+1;
        }
        return x;
    }
    
    int bfind_up(int x,int y,int v)
    {
        while(x<y)
        {
            int m=x+(y-x)/2;
            if (b[m]<=v) x=m+1;
            else y=m;
        }
        return x;
    }
    
    int main()
    {
        int n,m,x,y;
        while (scanf("%d",&n)!=EOF && n)
        {
            scanf("%d",&m);
            for (int i=1;i<=n;i++)
            scanf("%d",&b[i]);
            int nown=unique(n);
            buildtree(1,1,nown);
            for (int i=1;i<=m;i++)
            {
                scanf("%d%d",&x,&y);
                if (b[x]==b[y]) {printf("%d
    ",y-x+1);continue;}
                int xx=find(1,nown,b[x]);
                int yy=find(1,nown,b[y]);
                if (yy-xx==1){
                    int dx=bfind_up(1,n,b[x]); if (b[dx]>b[x]) dx--;
                    int dy=bfind_down(1,n,b[y]);
                    dx=dx-x+1; dy=y-dy+1;
                    printf("%d
    ",max(dx,dy));
                    continue;
                }
                xx++,yy--;
                int dx=bfind_up(1,n,b[x])-x;
                int dy=y-bfind_down(1,n,b[y])+1;
                printf("%d
    ",max(get_max(1,xx,yy),max(dx,dy)));
            }
        }
        return 0;
    }

    作者 chensunrise

    至少做到我努力了
  • 相关阅读:
    写了一个分页控件。
    职业规划
    程序员该做的事
    做就做最优秀的员工
    Tomcat+JSP经典配置实例
    2005年11月26日8点50左右,南昌地震。
    如何添加一个自定义的columnstyles 到设计器中,以便在设计时直接使用他们?
    Oracle 的入门心得【强烈推荐】
    如何随机显示记录条数的15% ?
    重写DataGrid的DataGridBoolColumn,添加bool值改变事件。
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3753525.html
Copyright © 2011-2022 走看看