传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3524
http://www.lydsy.com/JudgeOnline/problem.php?id=2223
【题解】
由于出现次数超过区间长度的一半的数最多只有1个,所以就可以分两半找了。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10, SN = 524288 * 20 + 5; const int mod = 1e9+7; int n, a[M], rt[M], p; struct CMT { int ch[SN][2], w[SN], siz; inline void set() { siz = 0; } inline void up(int x) { if(!x) return ; w[x] = w[ch[x][0]] + w[ch[x][1]]; } inline void edt(int &x, int y, int l, int r, int ps) { x = ++siz; ch[x][0] = ch[y][0], ch[x][1] = ch[y][1]; w[x] = w[y]; if(l == r) { ++ w[x]; return ; } int mid = l+r>>1; if(ps <= mid) edt(ch[x][0], ch[y][0], l, mid, ps); else edt(ch[x][1], ch[y][1], mid+1, r, ps); up(x); } inline int query(int x, int y, int l, int r) { if(w[y] - w[x] < p) return 0; if(l == r) return l; int mid = l+r>>1, p0 = w[ch[y][0]] - w[ch[x][0]], p1 = w[ch[y][1]] - w[ch[x][1]]; if(p0 > p) return query(ch[x][0], ch[y][0], l, mid); else if(p1 > p) return query(ch[x][1], ch[y][1], mid+1, r); else return 0; } }T; int main() { int Q, l, r; cin >> n >> Q; for (int i=1, t; i<=n; ++i) { scanf("%d", &t); T.edt(rt[i], rt[i-1], 1, n, t); } while(Q--) { scanf("%d%d", &l, &r); p=(r-l+1)/2; printf("%d ", T.query(rt[l-1], rt[r], 1, n)); } return 0; }