[bzoj3524/2223][Poi2014]Couriers_主席树
Couriers bzoj-3524 Poi-2014
题目大意:给定n个数的序列,询问区间内是否存在一个在区间内至少出现了(区间长度>>1)次的数。如果有,输出该数,反之输出0。
注释:$1\le n,m\le 5\cdot 10^5$。
想法:主席树裸题。
主流做法就是弄一个Existence数组询问有没有这样的数,然后查询区间中位数即可。
但是可以在query的时候强行查询,因为没有输出0,直接输出即可。
最后,附上丑陋的代码... ...
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define N 500010 using namespace std; int cnt[N<<5],ls[N<<5],rs[N<<5],tot; int a[N],b[N],root[N]; int build( int l, int r) { int pos=++tot,mid=(l+r)>>1; if (l==r) return pos; ls[pos]=build(l,mid); rs[pos]=build(mid+1,r); return pos; } int update( int pre, int l, int r, int k) { int pos=++tot,mid=(l+r)>>1; cnt[pos]=cnt[pre]+1; ls[pos]=ls[pre]; rs[pos]=rs[pre]; if (l==r) return pos; if (k<=mid) ls[pos]=update(ls[pre],l,mid,k); else rs[pos]=update(rs[pre],mid+1,r,k); return pos; } // bool Existence(int x,int y,int l,int r,int Want) // { // if(l==r) return (cnt[y]-cnt[x])>=Want; // int mid=(l+r)>>1; // int LR=1; // if(cnt[ls[y]]-cnt[ls[x]]>cnt[rs[y]]-cnt[rs[x]]) LR=0; // else if(cnt[ls[y]]-cnt[ls[x]]<cnt[rs[y]]-cnt[rs[x]]) LR=2; // if(LR==0) return Existence(ls[x],ls[y],l,mid,Want); // if(LR==2) return Existence(rs[x],rs[y],mid+1,r,Want); // return Existence(ls[x],ls[y],l,mid,Want)|Existence(rs[x],rs[y],mid+1,r,Want); // } // int query(int x,int y,int l,int r,int k) // { // int mid=(l+r)>>1; // if(l==r) return b[l]; // int dlt=cnt[ls[y]]-cnt[ls[x]]; // if(dlt>=k) return query(ls[x],ls[y],l,mid,k); // else return query(rs[x],rs[y],mid+1,r,k-dlt); // } int query( int x, int y, int l, int r, int k) { int mid=(l+r)>>1; if (l==r) return l; int L=cnt[ls[y]]-cnt[ls[x]],R=cnt[rs[y]]-cnt[rs[x]]; if (L>k) return query(ls[x],ls[y],l,mid,k); if (R>k) return query(rs[x],rs[y],mid+1,r,k); else return 0; } int main() { int n,m; cin >> n >> m ; for ( int i=1;i<=n;i++) scanf ( "%d" ,&a[i]) /* ,b[i]=a[i] */ ; sort(b+1,b+n+1); /* int len=unique(b+1,b+n+1)-b-1; */ root[0]=build(1,n); for ( int i=1;i<=n;i++) { // int t=lower_bound(b+1,b+n+1,a[i])-b; root[i]=update(root[i-1],1,n,a[i]); } for ( int x,y,i=1;i<=m;i++) { scanf ( "%d%d" ,&x,&y); // if(Existence(root[x-1],root[y],1,n,(y-x+1)/2+1)) printf("%d\n",query(root[x-1],root[y],1,n,(y-x+1)/2+1)); // else printf("0\n"); printf ( "%d\n" ,query(root[x-1],root[y],1,n,(y-x+1)>>1)); } return 0; } |
小结:主席树真强... ...
| 欢迎来原网站坐坐! >原文链接<
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步