【主席树】BZOJ3524-[Poi2014]Couriers

【题目大意】

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

【思路】

只有query部分需要稍作修改。由于每个节点代表的是一个大小区间数的总数,所以只需判断左右子数的sum值是否大于(r-l+1)/2,满足继续往左右子树查询。没有满足条件的就返回0。由于当前的节点的sum值一定是大于(r-l+1)/2的,如果l==r直接返回l即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #define lson l,m
 7 #define rson m+1,r
 8 using namespace std;
 9 const int MAXN=500000+50;
10 int n,m,d,a[MAXN],hash[MAXN],tot;
11 int T[MAXN],L[MAXN<<5],R[MAXN<<5],sum[MAXN<<5];
12 
13 int build(int l,int r)
14 {
15     int rt=++tot;
16     sum[rt]=0;
17     if (l!=r)
18     {
19         int m=(l+r)>>1;
20         L[rt]=build(lson);
21         R[rt]=build(rson);
22     }
23     return rt;
24 }
25 
26 int update(int pre,int l,int r,int x)
27 {
28     int rt=++tot;
29     L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1;
30     if (l!=r)
31     {
32         int m=(l+r)>>1;
33         if (x<=m) L[rt]=update(L[pre],lson,x);
34             else R[rt]=update(R[pre],rson,x);
35     }
36     return rt;
37 }
38 
39 int query(int lrt,int rrt,int l,int r,int k)
40 {
41     if (l==r) return l;
42     int m=(l+r)>>1;
43     if (sum[L[rrt]]-sum[L[lrt]]>k) return query(L[lrt],L[rrt],lson,k);
44     if (sum[R[rrt]]-sum[R[lrt]]>k) return query(R[lrt],R[rrt],rson,k);
45     return 0; 
46 } 
47 
48 void init()
49 {
50     scanf("%d%d",&n,&m);
51     for (int i=1;i<=n;i++) scanf("%d",&a[i]),hash[i]=a[i];
52     sort(hash+1,hash+n+1);
53     d=unique(hash+1,hash+n+1)-(hash+1);
54     
55     tot=0; 
56     T[0]=build(1,d);
57     for (int i=1;i<=n;i++)
58     {
59         int x=lower_bound(hash+1,hash+d+1,a[i])-hash;
60         //注意离散化之后是从1开始,所以减去的是hash而不是hash+1 
61         T[i]=update(T[i-1],1,d,x);
62     }
63 }
64 
65 void solve()
66 {
67     for (int i=0;i<m;i++)
68     {
69         int l,r;
70         scanf("%d%d",&l,&r);
71         int ans=query(T[l-1],T[r],1,d,(r-l+1)>>1);
72         printf("%d\n",hash[ans]);
73     }
74 }
75 
76 int main()
77 {
78     init();
79     solve();
80     return 0;    
81 } 

 

posted @ 2016-08-13 12:21  iiyiyi  阅读(158)  评论(0编辑  收藏  举报