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
题意:给出一个非降排列的整数数组,对于一系列询问(i,j),回答ai到aj中出现次数最多的值所出现的次数。
思路:建棵线段树,维护len,llen,rlen。即最长连续长度,左端的最长连续长度,右端的最长连续长度。
len的维护可能跨越左右子树,具体看代码。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 100080 #define lson id<<1,l,mid #define rson id<<1|1,mid+1,r int key[maxn]; struct ST { int id,l,r,llen,rlen,len; }st[maxn<<2]; inline int max(int a,int b) { return a>b?a:b; } inline int max(int a,int b,int c) { if(a < b) a = b; if(a < c) a = c; return a; } void PushUp(int id) { st[id].llen = st[id<<1].llen; st[id].rlen = st[id<<1|1].rlen; st[id].len = max(st[id<<1].len,st[id<<1|1].len); if(key[st[id].l] == key[st[id<<1].r] && key[st[id].l] == key[st[id<<1|1].l]) { st[id].llen = st[id<<1].llen + st[id<<1|1].llen; } if(key[st[id].r] == key[st[id<<1|1].l] && key[st[id].r] == key[st[id<<1].r]) { st[id].rlen = st[id<<1].rlen + st[id<<1|1].rlen; } if(key[st[id<<1].r] == key[st[id<<1|1].l]) { st[id].len = max(st[id].len,st[id<<1].rlen + st[id<<1|1].llen); } } void buildtree(int id,int l,int r) { st[id].l = l,st[id].r = r; if(l == r) { st[id].len = st[id].llen = st[id].rlen = 1; return; } int mid = (l + r)>>1; buildtree(lson); buildtree(rson); PushUp(id); } int query(int id,int l,int r) { if(st[id].l == l && st[id].r == r) return st[id].len; if(st[id<<1].r >= r) return query(id<<1,l,r); else if(st[id<<1|1].l <= l) return query(id<<1|1,l,r); else { int ans1 = query(id<<1,l,st[id<<1].r); int ans2 = query(id<<1|1,st[id<<1|1].l,r); int ans = max(ans1,ans2); if(key[st[id<<1].r] == key[st[id<<1|1].l]) { ans = max(ans,min(st[id<<1].rlen,st[id<<1].r - l + 1) + min(st[id<<1|1].llen,r - st[id<<1|1].l + 1)); } return ans; } } int main() { //freopen("in.txt","r",stdin); int n,q; while(scanf("%d",&n)!=EOF && n) { scanf("%d",&q); for(int i = 1;i <= n;i++) scanf("%d",&key[i]); buildtree(1,1,n); while(q--) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",query(1,u,v)); } } return 0; }
RMQ做法:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 100080 int d[maxn][20]; int key[maxn],R[maxn],L[maxn]; int n,q; inline int max(int a,int b,int c) { if(a < b) a = b; if(a < c) a = c; return a; } void RMQ_init() { for(int i = 1;i <= n;i++) d[i][0] = 1;//连续长度为1 for(int j = 1;(1 << j) <= n;j++) { for(int i = 1;i + (1 << j) - 1 <= n;i++) { d[i][j] = max(d[i][j-1],d[i+(1<<(j-1))][j-1]); int pos = i + (1 << (j-1)); d[i][j] = max(d[i][j],min(R[pos],i+(1<<j)-1) - max(i,L[pos]) + 1); } } } int RMQ(int l,int r) { int k = 0; while((1 << (k+1)) <= r - l + 1) k++; int pos = r - (1 << k) + 1; int ans = max(d[l][k],d[pos][k]); ans = max(ans,min(R[pos],r) - max(l,L[pos]) + 1); return ans; } int main() { //freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF && n) { scanf("%d",&q); for(int i = 1;i <= n;i++) scanf("%d",&key[i]); L[1] = R[1] = 1; int s = 1,t = 1; for(int i = 2;i <= n;i++) { if(key[i] == key[i-1]) { L[i] = L[i-1]; t = i; } else { L[i] = R[i] = i; for(int j = s;j <= t;j++) R[j] = t; s = t = i; } } for(int i = s;i <= t;i++) R[i] = n; RMQ_init(); while(q--) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",RMQ(u,v)); } } return 0; }