BZOJ_2223_[Coci 2009]PATULJCI_主席树
Description
Input
10 3 1 2 1 2 1 2 3 2 3 3 8 1 2 1 3 1 4 1 5 2 5 2 6 6 9 7 10
Output
no
yes 1
no
yes 1
no
yes 2
no
yes 3
yes 1
no
yes 1
no
yes 2
no
yes 3
区间众数,可以用主席树求。
查询时判断那边大走哪边。
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 300050 int t[N*20],ls[N*20],rs[N*20],n,m; int root[N],a[N],tot; struct A{ int num,id,v; }d[N]; bool cmp1(const A &x,const A &y){ return x.num<y.num; } bool cmp2(const A &x,const A &y){ return x.id<y.id; } void insert(int x,int &y,int l,int r,int val){ y=++tot; if(l==r) { t[y] = t[x] + 1; return ; } int mid=l+r>>1; if(val<=mid) rs[y]=rs[x],insert(ls[x],ls[y],l,mid,val); else ls[y]=ls[x],insert(rs[x],rs[y],mid+1,r,val); t[y]=t[ls[y]]+t[rs[y]]; } int query(int x,int y,int l,int r,int len){ if(l==r) return a[l]; int mid=l+r>>1,sizls=t[ls[y]]-t[ls[x]],sizrs=t[rs[y]]-t[rs[x]]; if(sizls>len/2) return query(ls[x],ls[y],l,mid,len); if(sizrs>len/2) return query(rs[x],rs[y],mid+1,r,len); return 0; } int main() { scanf("%d%*d",&n); int i,x,y,j; for(i=1;i<=n;i++) scanf("%d",&d[i].num),d[i].id=i; sort(d+1,d+n+1,cmp1);d[0].num=20003535; for(i=1,j=0;i<=n;i++) { if(d[i].num!=d[i-1].num)j++;d[i].v=j;a[j]=d[i].num; } sort(d+1,d+n+1,cmp2); for(i=1;i<=n;i++) insert(root[i-1],root[i],1,n,d[i].v); for(scanf("%d",&m),i=1;i<=m;i++) { scanf("%d%d",&x,&y); int tmp = query(root[x-1],root[y],1,n,y-x+1); if(tmp) { printf("yes %d\n",tmp); }else puts("no"); } }