D. Frequent values

D. Frequent values

3000ms
3000ms
131072KB
 
64-bit integer IO format: %lld      Java class name: Main
 
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

解题:注意处理边界,我的d存出现次数,是从左往右的,故左边界很需要处理!而右边界就不需要处理了。因为左边界的左边一个元素正是我们选取区间的最优值可能算入了边界左边的与边界相等的数值。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <vector>
 6 #include <climits>
 7 #include <algorithm>
 8 #include <cmath>
 9 #define LL long long
10 using namespace std;
11 const int maxn = 100010;
12 int d[maxn],dt[maxn];
13 struct node {
14     int lt,rt,val,index;
15 } tree[maxn<<2];
16 void build(int lt,int rt,int v) {
17     tree[v].lt = lt;
18     tree[v].rt = rt;
19     if(lt == rt) {
20         tree[v].val = d[lt];
21         tree[v].index = lt;
22         return;
23     }
24     int mid = (lt+rt)>>1;
25     build(lt,mid,v<<1);
26     build(mid+1,rt,v<<1|1);
27     if(tree[v<<1].val >= tree[v<<1|1].val) {
28         tree[v].val = tree[v<<1].val;
29         tree[v].index = tree[v<<1].index;
30     } else {
31         tree[v].val = tree[v<<1|1].val;
32         tree[v].index = tree[v<<1|1].index;
33     }
34     tree[v].val = max(tree[v<<1].val,tree[v<<1|1].val);
35 }
36 int query(int &index,int lt,int rt,int v) {
37     if(tree[v].lt == lt && tree[v].rt == rt) {
38         index = tree[v].index;
39         return tree[v].val;
40     };
41     int mid = (tree[v].lt+tree[v].rt)>>1;
42     int a,b,x,y;
43     if(rt <= mid) return query(index,lt,rt,v<<1);
44     else if(lt > mid) return query(index,lt,rt,v<<1|1);
45     else {
46         x = query(a,lt,mid,v<<1);
47         y = query(b,mid+1,rt,v<<1|1);
48         if(x >= y) {
49             index = a;
50             return x;
51         } else {
52             index = b;
53             return y;
54         }
55     }
56 }
57 int main() {
58     int n,m,i,x,y,temp,a,b,index,j;
59     while(scanf("%d",&n),n) {
60         scanf("%d",&m);
61         for(i = 1; i <= n; i++)
62             scanf("%d",dt+i);
63         temp = d[1] = 1;
64         for(i = 2; i <= n; i++) {
65             if(dt[i] == dt[i-1]) temp++;
66             else temp = 1;
67             d[i] = temp;
68         }
69         build(1,n,1);
70         for(i = 0; i < m; i++) {
71             scanf("%d %d",&x,&y);
72             temp = query(index,x,y,1);
73             if(dt[x] == dt[y]) printf("%d\n",y-x+1);
74             else if(x == 1 || dt[index] != dt[x-1]) printf("%d\n",temp);
75             else {
76                 for(j = x+1; dt[j] == dt[j-1] && j <= y; j++);
77                 temp = query(index,j,y,1);
78                 printf("%d\n",max(j-x,temp));
79             }
80         }
81     }
82     return 0;
83 }
View Code

 

RMQ

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 100010;
18 int a[maxn],b[maxn],c[maxn][20],n,m,s,t;
19 int main() {
20     while(scanf("%d",&n),n){
21         scanf("%d",&m);
22         for(int i = 0; i < n; i++)
23             scanf("%d",b+i);
24         int tmp = 1;
25         a[n-1] = tmp;
26         for(int i = n-2; i >= 0; i--){
27             if(b[i] == b[i+1]) ++tmp;
28             else tmp = 1;
29             a[i] = tmp;
30         }
31         for(int i = n-1; i >= 0; --i){
32             c[i][0] = a[i];
33             for(int j = 1; i + (1<<j) <= n; ++j)
34                 c[i][j] = max(c[i][j-1],c[i+(1<<(j-1))][j-1]);
35         }
36         while(m--){
37             scanf("%d %d",&s,&t);
38             --s;
39             --t;
40             tmp = lower_bound(b+s,b+t+1,b[t]) - b;
41             int ans = t - tmp + 1;
42             t = tmp - 1;
43             int r = log2(t - s + 1.0);
44             if(t <= s) printf("%d\n",ans);
45             else printf("%d\n",max(ans,max(c[s][r],c[t-(1<<r)+1][r])));
46         }
47     }
48     return 0;
49 }
View Code

 

posted @ 2014-07-13 22:02  狂徒归来  阅读(206)  评论(0编辑  收藏  举报