1. 程式人生 > >bzoj3524/2223 [Poi2014]Couriers

bzoj3524/2223 [Poi2014]Couriers

hide n) img main urn 出現 set bzoj using

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=3524

http://www.lydsy.com/JudgeOnline/problem.php?id=2223

【題解】

由於出現次數超過區間長度的一半的數最多只有1個,所以就可以分兩半找了。。

技術分享
# 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\n", T.query(rt[l-1], rt[r], 1, n)); } return 0; }
View Code

bzoj3524/2223 [Poi2014]Couriers