hdu 1806 Frequent values(二分+线段树)
2014-05-05 19:50
375 查看
Frequent values
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1050 Accepted Submission(s): 375
[align=left]Problem Description[/align]
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 .
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.
[align=left]Sample Input[/align]
10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0
[align=left]Sample Output[/align]
1 4 3 样例:其余你应该知道怎么做了! [code]#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <cstdlib> using namespace std; const int maxn = 100010; int v[maxn] , sum[maxn]; struct tree{ int l , r , Max; tree(int a = 0 , int b = 0 , int c = 0){ l = a , r = b , Max = c; } }a[4*maxn]; int n , q , cnt; void build(int l , int r , int k){ a[k].l = l; a[k].r = r; if(l == r){ a[k].Max = v[l]; }else{ int mid = (l+r)/2; build(l , mid , 2*k); build(mid+1 , r , 2*k+1); a[k].Max = max(a[2*k].Max , a[2*k+1].Max); } } int querry(int l , int r , int k){ if(l <= a[k].l && a[k].r <= r){ return a[k].Max; }else{ int mid = (a[k].l+a[k].r)/2; if(mid >= r) return querry(l , r , 2*k); else if(mid < l) return querry(l , r , 2*k+1); else return max(querry(l , mid , 2*k) , querry(mid+1 , r , 2*k+1)); } } void initial(){ cnt = 1; for(int i = 0; i < maxn; i++){ v[i] = 0; sum[i] = 0; } } void readcase(){ cin >> q; int num , pre; cin >> pre; v[1] = 1; for(int i = 1; i < n; i++){ scanf("%d" , &num); if(num == pre) v[cnt]++; else{ cnt++; v[cnt]++; pre = num; } } for(int i = 1; i <= cnt; i++){ sum[i] = sum[i-1]+v[i]; } } int binary_search(int k){ int l = 1 , r = cnt; while(l < r){ int mid = (l+r)/2; if(sum[mid] >= k){ r = mid; }else{ l = mid+1; } } return l; } void computing(){ build(1 , cnt , 1); int i , j , ans; while(q--){ //cin >> i >> j; scanf("%d%d" , &i ,&j); int L = binary_search(i); int R = binary_search(j); if(L == R) printf("%d\n" , j-i+1); else{ ans = max(sum[L]-i+1 , j-sum[R-1]); if(L+1 <= R-1) ans = max(ans , querry(L+1 , R-1 , 1)); printf("%d\n" , ans); } } } int main(){ while(cin >> n && n){ initial(); readcase(); computing(); } return 0; }
[/code]
相关文章推荐
- HDU 1806 Frequent values(线段树+离散化+二分)
- hdu 1806 Frequent values 线段树
- hdu 1806(线段树区间合并)
- POJ 2892 Tunnel Warfare || HDU 1540(树状数组+二分 || 线段树的单点更新+区间查询)
- hdu 6070 Dirt Ratio(二分+线段树维护区间最小值)
- HDU 6070 二分查找 + 线段树 + 枚举
- 【HDU 6070 Dirt Ratio】 二分 & 线段树
- HDU 6070 Dirt Ratio(二分+线段树)
- [HDU 1806] Frequent values
- HDU 4614 Vases and Flowers (线段树[区间赋值+区间求和] + 二分)
- HDU 4614 Vases and Flowers [二分 + 线段树]
- HDU 4006 The kth great number【线段树二分】
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio二分 线段树
- hdu-4614-Vases and Flowers(线段树,区间更新区间查询,lazy,二分)
- 2016 多校第一场 hdu 5276((线段树+暴力打表)|(RMQ + 二分))
- HDU 1806(Frequent values)莫队算法
- HDU 4614 Vases and Flowers [二分 + 线段树]
- HDU 4614 Vases and Flowers(线段树区间更新+二分)
- HDU 6070 Dirt Ratio 分数规划 二分 线段树维护区间最值