BZOJ3524: [Poi2014]Couriers

题解: 直接主席树查询即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <bits/stdc++.h>
const int MAXN=5e5+10;
using namespace std;
typedef struct node{
    int l,r,sum;
}node;
node d[MAXN*21];int a[MAXN],cnt,rt[MAXN];
void update(int &x,int y,int l,int r,int t){
    x=++cnt;d[x]=d[y];d[x].sum++;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(t<=mid)update(d[x].l,d[y].l,l,mid,t);
    else update(d[x].r,d[y].r,mid+1,r,t);
}
int ans,key;
void querty(int x,int y,int l,int r){
    if(l==r){ans=l;return ;}
    int mid=(l+r)>>1;
    if(d[d[y].l].sum-d[d[x].l].sum>key)querty(d[x].l,d[y].l,l,mid);
    if(d[d[y].r].sum-d[d[x].r].sum>key)querty(d[x].r,d[y].r,mid+1,r);
}
int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),update(rt[i],rt[i-1],1,n,a[i]);
    int l,r;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&l,&r);key=(r-l+1)/2;
        ans=0;querty(rt[l-1],rt[r],1,n);
        printf("%d\n",ans);
    }
    return 0;
}

 

3524: [Poi2014]Couriers

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 2825  Solved: 1150
[Submit][Status][Discuss]

Description

给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

Input

第一行两个数n,m。
第二行n个数,a[i]。
接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

Output

m行,每行对应一个答案。

Sample Input

7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6

Sample Output

1
0
3
0
4

HINT

【数据范围】

n,m≤500000

 

2016.7.9重设空间,但未重测!

posted @   wang9897  阅读(123)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示