bzoj3524 Couriers
题目大意:给出一段区间,求所求区间中出现次数超过区间长一半的数,若没有则输出0。
主席树的题吖……
可以说很裸了。
代码:
#include<cstdio> #include<algorithm> using namespace std; #define N 500050 int n,m,mx,a[N]; struct ND { int x,id; }nd[N]; bool cmp(ND a,ND b) { return a.x<b.x; } int to[N],rt[N],tot; struct segtree { int ls,rs,v; }tr[30*N]; void update(int u) { tr[u].v = tr[tr[u].ls].v+tr[tr[u].rs].v; } void insert(int l,int r,int &u,int k,int qx) { u=++tot; tr[u]=tr[k]; if(l==r) { tr[u].v++; return ; } int mid = (l+r)>>1; if(qx<=mid)insert(l,mid,tr[u].ls,tr[k].ls,qx); else insert(mid+1,r,tr[u].rs,tr[u].rs,qx); update(u); } int query(int l,int r,int a,int b,int x) { if(l==r)return l; int mid = (l+r)>>1; if(2*(tr[tr[b].ls].v-tr[tr[a].ls].v)>x)return query(l,mid,tr[a].ls,tr[b].ls,x); else if(2*(tr[tr[b].rs].v-tr[tr[a].rs].v)>x)return query(mid+1,r,tr[a].rs,tr[b].rs,x); return 0; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&nd[i].x); nd[i].id=i; } sort(nd+1,nd+1+n,cmp); int las = -1; for(int i=1;i<=n;i++) { if(las!=nd[i].x) { las=nd[i].x; to[++mx] = nd[i].x; } a[nd[i].id]=mx; } for(int i=1;i<=n;i++) { insert(1,mx,rt[i],rt[i-1],a[i]); } for(int l,r,i=1;i<=m;i++) { scanf("%d%d",&l,&r); int ans = query(1,mx,rt[l-1],rt[r],r-l+1); ans = to[ans]; printf("%d\n",ans); } return 0; }