【poj 3368 】 Frequent values 线段树应用

Frequent values
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 15940 Accepted: 5802

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
Ulm Local 2007

题目链接:http://poj.org/status

题意:给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数。

思路:因为数字的连续性–》最长连续字段的想法,lx,rx分别代表自左,自右的最长数;
更新:

void push_up(int id,int l,int r)
{
    int mid=(l+r)>>1;
    if(a[mid]==a[mid+1])tr[id].val=max(tr[lson].rx+tr[rson].lx,max(tr[lson].val,tr[rson].val));
    else tr[id].val=max(tr[lson].val,tr[rson].val);//!!!分别max,不与自己比(WA 点)

    if(tr[lson].lx==mid-l+1&&a[mid]==a[mid+1])
    tr[id].lx=tr[lson].rx+tr[rson].lx;
    else tr[id].lx=tr[lson].lx;

    if(tr[rson].rx==r-mid&&a[mid]==a[mid+1])
    tr[id].rx=tr[rson].lx+tr[lson].rx;
    else tr[id].rx=tr[rson].rx;
}

没有修改,一遍build;
query时分情况讨论,注意跨区间的讨论:if(a[mid+1]==a[mid]) m=min(mid-l+1,tr[lson].rx)+min(r-mid,tr[rson].lx);


#include<iostream>
#include<stdio.h>
#include<string.h>
#define lson (id*2)
#define rson (id*2+1)
using namespace std;
struct node{
    int lx,rx,val;
}tr[100002*8];
int a[200005];
int n,m;
int ans;
void push_up(int id,int l,int r)
{
    int mid=(l+r)>>1;
    if(a[mid]==a[mid+1])tr[id].val=max(tr[lson].rx+tr[rson].lx,max(tr[lson].val,tr[rson].val));
    else tr[id].val=max(tr[lson].val,tr[rson].val);

    if(tr[lson].lx==mid-l+1&&a[mid]==a[mid+1])
    tr[id].lx=tr[lson].rx+tr[rson].lx;
    else tr[id].lx=tr[lson].lx;

    if(tr[rson].rx==r-mid&&a[mid]==a[mid+1])
    tr[id].rx=tr[rson].lx+tr[lson].rx;
    else tr[id].rx=tr[rson].rx;
}
void build(int id,int l,int r)
{
    if(l==r)
    {
        tr[id].lx=tr[id].rx=tr[id].val=1;
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    push_up(id,l,r);
    //cout<<l<<" "<<r<<" "<<tr[id].val<<endl;
}
int query(int id,int L,int R,int l,int r)
{
    if(L>r||R<l||R<L) return 0;
    if(L>=l&&R<=r) return tr[id].val;
    int mid=(L+R)>>1;
    int m=1,m1=1,m2=1;
    if(a[mid+1]==a[mid]) m=min(mid-l+1,tr[lson].rx)+min(r-mid,tr[rson].lx);
    if(l<=mid)
    m1=query(lson,L,mid,l,r);
    if(r>mid)
    m2=query(rson,mid+1,R,l,r);
    m=max(max(m1,m2),m);
    return m;

}
int main()
{
    while(scanf("%d",&n))
    {
        if(n==0) return 0;
        int aa,bb;
        scanf("%d",&m);
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&aa,&bb);
            printf("%d\n",query(1,1,n,aa,bb));
        }

    }

}

你可能感兴趣的:(poj)