您的位置:首页 > 其它

bzoj3524/2223 [Poi2014]Couriers

2017-07-15 17:50 381 查看
传送门: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: