内部赛3 F Frequent values

来源:互联网 发布:java 判断日期相等 编辑:程序博客网 时间:2024/05/30 12:30

Frequent values

Time Limit: 1000MS Memory limit: 65536K

题目描述

You are given asequence of n integers a1 ,a2 , ... ,an innon-decreasing order. In addition to that, you are given severalqueries consisting of indices i and j (1≤ i ≤ j ≤ n). For each query, determine the most frequent valueamong the integers ai , ... ,aj.

输入

The input consists of several testcases. Each test case starts with a line containing twointegers 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 foreach i∈ {1, ..., n-1}: ai ≤ai+1.The following q linescontain one query each, consisting of two integers i and j (1≤ i ≤ j ≤ n), which indicate the boundary indices for thequery.

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

输出

For each query, print one line withone integer: The number of occurrences of the most frequent valuewithin the given range.


示例输入

10 3-1 -1 1 1 1 1 3 10 10 102 31 105 100

示例输出

143

这个题题意简单我首先是想到的是线段树,在写代码时思路他一定要理清,不然很容易在递归中陷进去,代码有点长,不过听大宝说还有简单的方法,等学会了在贴一遍吧!

代码:

#include<stdio.h>

#define N 100005

struct node
{
 int l,r,count,num;
 int rnum,lnum;
 int lcount,rcount;
}tree[N*4];

int a[N],MAX;
void maketree(int t,int l,int r)
{
 int mid,sum;
 tree[t].l=l;
 tree[t].r=r;
 if(l==r)
 {
  tree[t].count=tree[t].lcount=tree[t].rcount=1;
  tree[t].num=tree[t].lnum=tree[t].rnum=a[l];
  return;
 }
 mid=(l+r)/2;
 maketree(2*t,l,mid);
 maketree(2*t+1,mid+1,r);

 if(tree[2*t].count>tree[2*t+1].count)
 {
  tree[t].count=tree[2*t].count;
  tree[t].num=tree[2*t].num;
 }
 else
 {
  tree[t].count=tree[2*t+1].count;
  tree[t].num=tree[2*t+1].num;
 }
 tree[t].lnum=tree[2*t].lnum;
 tree[t].lcount=tree[2*t].lcount;
 tree[t].rnum=tree[2*t+1].rnum;
 tree[t].rcount=tree[2*t+1].rcount;
 if(tree[2*t].rnum==tree[2*t+1].lnum)
 {
  sum=tree[2*t].rcount+tree[2*t+1].lcount;
  if(sum>tree[t].count)
  {
   tree[t].count=sum;
   tree[t].num=tree[2*t].rnum;
  }
  if(tree[2*t].lnum==tree[2*t+1].lnum)
   tree[t].lcount+=tree[2*t+1].lcount;
  if(tree[2*t].rnum==tree[2*t+1].rnum)
   tree[t].rcount+=tree[2*t].rcount;
 }
}

void search(int t,int l,int r)
{
 int mid;
 int sum1,sum2;
 if(tree[t].l==l&&tree[t].r==r)
 {
  if(tree[t].count>MAX)
   MAX=tree[t].count;
  return;
 }
 if(r<=tree[2*t].r)
  search(2*t,l,r);
 else if(l>=tree[2*t+1].l)
  search(2*t+1,l,r);
 else
 {
  mid=(tree[t].l+tree[t].r)/2;
  search(2*t,l,mid);
  search(2*t+1,mid+1,r);
  if(tree[2*t].rnum ==tree[2*t+1].lnum)
       {
           if(a[l]!=tree[2*t].rnum)
    sum1=tree[2*t].rcount;
           else
    sum1=mid-l+1;
           if(a[r]!=tree[2*t+1].lnum) sum2=tree[2*t+1].lcount;
           else
    sum2=r-mid;
           if(sum1+sum2 > MAX) MAX=sum1+sum2;
       }
 }
}


int main()
{
 int n,m;
 int i,j;
 int x,y;
 while(scanf("%d%d",&n,&m),n)
 {
  for(i=1;i<=n;i++)
  {
   scanf("%d",&a[i]);
  }
  maketree(1,1,n);
  for(j=0;j<m;j++)
  {
   MAX=0;
   scanf("%d%d",&x,&y);
   search(1,x,y);
   printf("%d\n",MAX);
  }
 }
 return 0;
}