2007/2008 ACM International Collegiate Programming Contest University of Ulm Local Contest
Problem F: Frequent values
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 Specification
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 Specification
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
题目描述:求某段给定区间内出现最多的数出现的次数,这个序列数不下降的
由于不下降,所有相等的数会聚集在一起,采用游程编码,
(a,b)表示有b个连续的a.
由于不改变某个点的值,可以采用RMQ或者线段树进行统计.
体会到递推最重要的就是递推顺序和初始化。
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define maxn 100100 #define LL long long using namespace std; int value[maxn]; int count_[maxn]; int num[maxn]; int Left[maxn]; int Right[maxn]; int a[maxn]; LL MAXN[maxn*4]; LL d[maxn][30]; int n,q; int ql,qr; /*int op,ql,qr,p,v; void update(int o,int L,int R) { int M=L+(R-L)/2; if(L==R) MAXN[o]=v; else { if(p<=M) update(o*2,L,M); else update(o*2+1,M+1,R); MAXN[o]=max(MAXN[o*2],MAXN[o*2+1]); } } LL query(int o,int L,int R) { int M=L+(R-L)/2; LL ans=-1000; if(ql<=L && R<=qr) return MAXN[o]; if(ql<=M) ans=max(ans,query(o*2,L,M)); if(M<qr) ans=max(ans,query(o*2+1,M+1,R)); return ans; }*/ void init() { memset(count_,0,sizeof(count_)); memset(MAXN,0,sizeof(MAXN)); } LL Max(LL a,LL b) { if(a>=b) return a; else return b; } void RMQ_init(int t) { //for(int i=1;i<=n;i++) //d[i][0]=b[i]; for(int j=1;(1<<j)<=t;j++) { for(int i=1;i<=t;i++) { if( (i+(1<<j)-1) <=t ) { d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]); //printf("%d %d %lld ",i,j,d[i][j]); } } // printf(" "); } } LL RMQ(int L,int R,int t) { int k=0; while((1<<k+1)<= (R-L)+1 ) k++; return max(d[L][k],d[R-(1<<k)+1][k]); } int main() { while(~scanf("%d",&n) && n!=0) { scanf("%d",&q); init(); int t=0; a[0]=maxn; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]==a[i-1]) { count_[t]++; num[i]=t; } else { if(t!=0) { for(int k=i-count_[t];k<=i-1;k++) { Left[k]=(i-count_[t]); Right[k]=i-1; } } value[++t]=a[i]; ++count_[t]; num[i]=t; } } for(int k=n-count_[t]+1;k<=n;k++) { Left[k]=(n-count_[t]+1); Right[k]=n; } for(int i=1;i<=t;i++) { // cout<<count_[i]<<" "; // p=i; //v=count_[i]; // update(1,1,t); d[i][0]=count_[i]; } RMQ_init(t); // for(int i=1;i<=7;i++) // printf("%d ",MAXN[i]); /* for(int i=1;i<=n;i++) { printf("%d %d ",Left[i],Right[i]); } printf(" "); */int LLL,RRR; for(int j=1;j<=q;j++) { LL answer=0; scanf("%d%d",&LLL,&RRR); if(Right[LLL]==Right[RRR] && Left[LLL]==Left[RRR]) printf("%d ",(RRR-LLL)+1); else { answer=Max(answer,Right[LLL]-LLL+1); answer=Max(answer,RRR-Left[RRR]+1); ql=num[LLL]+1;qr=num[RRR]-1; /* cout<<Right[LLL]-LLL+1<<endl; cout<<RRR-Left[RRR]+1<<endl; cout<<ql<<endl; cout<<qr<<endl; */if(ql<=qr) answer=Max(answer,RMQ(ql,qr,t)); //cout<<query(1,1,t)<<endl; printf("%lld ",answer); } } } return 0; }
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define maxn 100100 #define LL long long using namespace std; int value[maxn]; int count_[maxn]; int num[maxn]; int Left[maxn]; int Right[maxn]; int a[maxn]; LL MAXN[maxn*4]; int n,q; int op,ql,qr,p,v; void update(int o,int L,int R) { int M=L+(R-L)/2; if(L==R) MAXN[o]=v; else { if(p<=M) update(o*2,L,M); else update(o*2+1,M+1,R); MAXN[o]=max(MAXN[o*2],MAXN[o*2+1]); } } LL query(int o,int L,int R) { int M=L+(R-L)/2; LL ans=-1000; if(ql<=L && R<=qr) return MAXN[o]; if(ql<=M) ans=max(ans,query(o*2,L,M)); if(M<qr) ans=max(ans,query(o*2+1,M+1,R)); return ans; } void init() { memset(count_,0,sizeof(count_)); memset(MAXN,0,sizeof(MAXN)); } LL Max(LL a,LL b) { if(a>=b) return a; else return b; } int main() { while(~scanf("%d",&n) && n!=0) { scanf("%d",&q); init(); int t=0; a[0]=maxn; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]==a[i-1]) { count_[t]++; num[i]=t; } else { if(t!=0) { for(int k=i-count_[t];k<=i-1;k++) { Left[k]=(i-count_[t]); Right[k]=i-1; } } value[++t]=a[i]; ++count_[t]; num[i]=t; } } for(int k=n-count_[t]+1;k<=n;k++) { Left[k]=(n-count_[t]+1); Right[k]=n; } for(int i=1;i<=t;i++) { // cout<<count_[i]<<" "; p=i; v=count_[i]; update(1,1,t); } // for(int i=1;i<=7;i++) // printf("%d ",MAXN[i]); /* for(int i=1;i<=n;i++) { printf("%d %d ",Left[i],Right[i]); } printf(" "); */int LLL,RRR; for(int j=1;j<=q;j++) { LL answer=0; scanf("%d%d",&LLL,&RRR); if(Right[LLL]==Right[RRR] && Left[LLL]==Left[RRR]) printf("%d ",(RRR-LLL)+1); else { answer=Max(answer,Right[LLL]-LLL+1); answer=Max(answer,RRR-Left[RRR]+1); ql=num[LLL]+1;qr=num[RRR]-1; /* cout<<Right[LLL]-LLL+1<<endl; cout<<RRR-Left[RRR]+1<<endl; cout<<ql<<endl; cout<<qr<<endl; */if(ql<=qr) answer=Max(answer,query(1,1,t)); //cout<<query(1,1,t)<<endl; printf("%lld ",answer); } } } return 0; }