BZOJ 3524 [POI2014]KUR-Couriers (主席树)

 题目大意:给你一个序列,求某个区间出现次数大于一半的数是什么

主席树裸题,刷刷水题提升自信= =

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define ll long long 
 5 #define il inline
 6 #define N 500100
 7 using namespace std;
 8 //re
 9 int n,m,tot;
10 int a[N],root[N];
11 struct Seg{
12     int ls,rs,sum;
13 }seg[N*30];
14 
15 int gc()
16 {
17     int rett=0,fh=1;char p=getchar();
18     while(p<'0'||p>'9'){if(p=='-')fh=-1;p=getchar();}
19     while(p>='0'&&p<='9'){rett=(rett<<3)+(rett<<1)+p-'0';p=getchar();}
20     return rett*fh;
21 }
22 il void pushup(int rt){seg[rt].sum=seg[seg[rt].ls].sum+seg[seg[rt].rs].sum;}
23 void build(int l,int r,int rt)
24 {
25     if(l==r) return;
26     int mid=(l+r)>>1;
27     seg[rt].ls=++tot,build(l,mid,tot);
28     seg[rt].rs=++tot,build(mid+1,r,tot);
29 }
30 void update(int x,int l,int r,int rt1,int rt2,int val)
31 {
32     if(l==r) {seg[rt2].sum+=val;return;}
33     int mid=(l+r)>>1;
34     if(x<=mid){
35         if(!seg[rt2].ls||seg[rt2].ls==seg[rt1].ls){
36             seg[rt2].ls=++tot,seg[seg[rt2].ls].sum=seg[seg[rt1].ls].sum;
37             if(!seg[rt2].rs) seg[rt2].rs=seg[rt1].rs;
38         }update(x,l,mid,seg[rt1].ls,seg[rt2].ls,val);
39     }else{
40         if(!seg[rt2].rs||seg[rt2].rs==seg[rt1].rs){
41             seg[rt2].rs=++tot,seg[seg[rt2].rs].sum=seg[seg[rt1].rs].sum;
42             if(!seg[rt2].ls) seg[rt2].ls=seg[rt1].ls;
43         }update(x,mid+1,r,seg[rt1].rs,seg[rt2].rs,val);
44     }pushup(rt2);
45 }
46 int query(int l,int r,int rt1,int rt2,int len)
47 {
48     if(l==r) return l;
49     int mid=(l+r)>>1;
50     if(seg[seg[rt2].ls].sum-seg[seg[rt1].ls].sum>=len) 
51         return query(l,mid,seg[rt1].ls,seg[rt2].ls,len);
52     if(seg[seg[rt2].rs].sum-seg[seg[rt1].rs].sum>=len) 
53         return query(mid+1,r,seg[rt1].rs,seg[rt2].rs,len);
54     return 0;
55 }
56 
57 int main()
58 {
59     //freopen("data.in","r",stdin);
60     scanf("%d%d",&n,&m);
61     for(int i=1;i<=n;i++) a[i]=gc();
62     root[0]=++tot,build(1,n,tot);
63     for(int i=1;i<=n;i++)
64         root[i]=++tot,update(a[i],1,n,root[i-1],root[i],1);
65     int x,y;
66     while(m--)
67     {
68         x=gc(),y=gc();
69         printf("%d\n",query(1,n,root[x-1],root[y],(y-x+1)/2+1));
70     }
71     return 0;
72 }

 

posted @ 2018-09-24 22:28  guapisolo  阅读(106)  评论(0编辑  收藏  举报