zoukankan      html  css  js  c++  java
  • POJ 3368 Frequent values (线段树)

    Frequent values
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 11083   Accepted: 4063

    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

    Source

    题意:一个具有n(1~100000)个点的序列,从大到小排序,有一些点的大小是相等的,问区间[a,b]上,相等大小的点最多是几个。

    思路:线段树+离散化。离散的运用:将连续的相等的一个区间的点集,聚集为线段树的一个节点,并且在这个节点上有信息能体现出这个区间的性质。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int N=100010;
    
    #define L(rt) (rt<<1)
    #define R(rt) (rt<<1|1)
    
    struct Tree{
        int l,r;
        int len;    //  len保存这个点集的点的数量
    }tree[N<<2];
    
    struct Point{
        int x,y;
    }seg[N];
    
    int num[N],hash[N];
    
    void PushUp(int rt){
        tree[rt].len=max(tree[L(rt)].len,tree[R(rt)].len);
    }
    
    void build(int l,int r,int rt){
        tree[rt].l=l;
        tree[rt].r=r;
        if(l==r){   
            tree[rt].len=seg[l].y-seg[l].x+1;
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,L(rt));
        build(mid+1,r,R(rt));
        PushUp(rt);
    }
    
    int ans;
    
    void query(int L,int R,int rt){
        if(tree[rt].l==L && tree[rt].r==R){
            ans=max(ans,tree[rt].len);
            return ;
        }
        int mid=(tree[rt].l+tree[rt].r)>>1;
        if(R<=mid)
            query(L,R,L(rt));
        else if(L>=mid+1)
            query(L,R,R(rt));
        else{
            query(L,mid,L(rt));
            query(mid+1,R,R(rt));
        }
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int n,m;
        while(~scanf("%d",&n) && n){
            scanf("%d",&m);
            for(int i=1;i<=n;i++)
                scanf("%d",&num[i]);
            int cnt=0,pre=999999;
            for(int i=1;i<=n;i++){   //  离散化,将点的序列离散化为一个个的点集
                if(num[i]!=pre){
                    pre=num[i];
                    cnt++;
                    seg[cnt].x=i;
                    seg[cnt].y=i;
                }else
                    seg[cnt].y=i;
                hash[i]=cnt;        //  hash保存序列上第i个点,对应的点集的下标
            }
            build(1,cnt,1);
            int a,b;
            while(m--){
                scanf("%d%d",&a,&b);
                int loc1=hash[a];   //如下,好的主函数操作能很大程度上简化线段树的复杂度
                int loc2=hash[b];
                if(loc1==loc2)      //  情况1:[a,b]为一个点集
                    printf("%d\n",b-a+1);
                else{               //  情况2,3:[a,b]包含多个点集
                    int n1=seg[loc1].y-a+1;
                    int n2=0;
                    int n3=b-seg[loc2].x+1;
                    if(loc2-loc1>1){    //情况3:[a,b]包含3个以上点集,中间点集最大值用到线段树
                        ans=0;
                        query(loc1+1,loc2-1,1);
                        n2=ans;
                    }
                    printf("%d\n",max(n1,max(n2,n3)));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    ural 1146. Maximum Sum(动态规划)
    ural 1119. Metro(动态规划)
    ural 1013. K-based Numbers. Version 3(动态规划)
    Floyd算法
    杭电21题 Palindrome
    杭电20题 Human Gene Functions
    杭电15题 The Cow Lexicon
    杭电三部曲一、基本算法;19题 Cow Bowling
    杭电1002 Etaoin Shrdlu
    Qt 学习之路 2(37):文本文件读写
  • 原文地址:https://www.cnblogs.com/jackge/p/3041698.html
Copyright © 2011-2022 走看看