【BZOJ】3524: [Poi2014]Couriers
【算法】主席树
【题解】例题,记录和,数字出现超过一半就递归查找。
主席树见【算法】数据结构
#include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespace std; int read() { char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c=='-')t=-1; do{s=s*10+c-'0';}while(isdigit(c=getchar())); return s*t; } const int maxn=500010; struct tree{int l,r,sum;}t[maxn*20]; int n,m,sz,root[maxn]; void insert(int L,int R,int x,int &y,int v){ y=++sz; t[y]=t[x];t[y].sum++; if(L==R)return; int mid=(L+R)>>1; if(v<=mid)insert(L,mid,t[x].l,t[y].l,v); else insert(mid+1,R,t[x].r,t[y].r,v); } int ask(int L,int R,int x,int y,int v){ if(L==R)return L; else{ int mid=(L+R)>>1; if(v<t[t[y].l].sum-t[t[x].l].sum)return ask(L,mid,t[x].l,t[y].l,v);else if(v<t[t[y].r].sum-t[t[x].r].sum)return ask(mid+1,R,t[x].r,t[y].r,v);else return 0; } } int main(){ scanf("%d%d",&n,&m); int u; for(int i=1;i<=n;i++){ u=read(); insert(1,n,root[i-1],root[i],u); } int v; for(int i=1;i<=m;i++){ u=read();v=read(); printf("%d\n",ask(1,n,root[u-1],root[v],(v-u+1)>>1)); } return 0; }