BZOJ2223/3524:[POI2014] Couriers(主席树)

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

Solution

就是递归查询区间sum是否大于(r-l+1)/2,是的话就递归左右儿子,否则return
如果能一直递归到l==r就是有解,否则无解

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define N (300000+100)
 6 using namespace std;
 7 struct node{int lson,rson,sum;}Segt[N*40];
 8 int a[N],b[N],n,m,Root[N],Segt_cnt,x,y,lim;
 9 
10 int Build(int l,int r)
11 {
12     int node=++Segt_cnt;
13     if (l==r) return node;
14     int mid=(l+r)>>1;
15     Segt[node].lson=Build(l,mid);
16     Segt[node].rson=Build(mid+1,r);
17     return node;
18 }
19 
20 int Update(int pre,int l,int r,int x)
21 {
22     int node=++Segt_cnt;
23     Segt[node].sum=Segt[pre].sum+1;
24     Segt[node].lson=Segt[pre].lson;
25     Segt[node].rson=Segt[pre].rson;
26     if (l==r) return node;
27     int mid=(l+r)>>1;
28     if (x<=mid) Segt[node].lson=Update(Segt[node].lson,l,mid,x);
29     else Segt[node].rson=Update(Segt[node].rson,mid+1,r,x);
30     return node;
31 }
32 
33 int Query(int u,int v,int l,int r)
34 {
35     int mid=(l+r)>>1,c=Segt[v].sum-Segt[u].sum;
36     if (c<=(y-x+1)>>1) return 0;
37     if (l==r) return b[l];    
38     return max(Query(Segt[u].lson,Segt[v].lson,l,mid),Query(Segt[u].rson,Segt[v].rson,mid+1,r));
39 }
40 
41 int main()
42 {
43     scanf("%d%d",&n,&lim);
44     for (int i=1;i<=n;++i)
45         scanf("%d",&a[i]),b[i]=a[i];
46     sort(b+1,b+n+1);
47     int num=unique(b+1,b+n+1)-b-1;
48     Root[0]=Build(1,num);
49     for (int i=1;i<=n;++i)
50     {
51         int t=lower_bound(b+1,b+num+1,a[i])-b;
52         Root[i]=Update(Root[i-1],1,num,t);
53     }
54     scanf("%d",&m);
55     for (int i=1;i<=m;++i)
56     {
57         scanf("%d%d",&x,&y);
58         int ans=Query(Root[x-1],Root[y],1,num);
59         if (ans) printf("yes %d\n",ans);
60         else printf("no\n");
61     }
62 }

 

posted @ 2018-04-01 11:03  Refun  阅读(214)  评论(0编辑  收藏  举报