bzoj 2223: [Coci 2009]PATULJCI

来源:互联网 发布:cf手游安卓版飞天软件 编辑:程序博客网 时间:2024/05/16 16:13

Description

Input

Output

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

Sample Input

no
yes 1
no
yes 1
no
yes 2
no
yes 3

Sample Output

HINT

Notice:输入第二个整数是序列中权值的范围Lim,即1<=ai(1<=i<=n)<=Lim。

1<=Lim<=10000


题目特意规定了询问的是出现次数超过一半以上的数,这意味着什么呢。

我们可以根据这点想到区间k大的查询。不同的是,我们这次直接找出现一半以上的数就可以了。

用主席树就可以搞定。

#include<cstdio>#include<algorithm>using namespace std;struct tree{     int l,r;     int ll,rr;     int s;}tr[8000001];int tot;struct number{     int x,t;     bool operator< (number xt) const     {          return x<xt.x;     }}a[500001];int f[500001],fx[500001];int pl[500001];inline void build(int l,int r){     int p=tot;     tr[p].l=l;     tr[p].r=r;     if(l!=r)     {          int mid=(l+r)/2;          tot++;          tr[p].ll=tot;          build(l,mid);          tot++;          tr[p].rr=tot;          build(mid+1,r);     }}inline int add(int p,int l,int r,int x){ if(p==0)      return 0;     if(tr[p].l==l&&tr[p].r==r)     {          tot++;          tr[tot].l=l;          tr[tot].r=r;          tr[tot].s=tr[p].s+x;          return tot;     }     else     {          int mid=(tr[p].l+tr[p].r)/2;          tot++;          int pp=tot;          tr[pp].l=tr[p].l;          tr[pp].r=tr[p].r;          if(l<=mid)               tr[pp].ll=add(tr[p].ll,l,r,x);          else               tr[pp].ll=tr[p].ll;          if(r>mid)               tr[pp].rr=add(tr[p].rr,l,r,x);          else               tr[pp].rr=tr[p].rr;          tr[pp].s=tr[tr[pp].ll].s+tr[tr[pp].rr].s;          return pp;     }}inline int find(int p1,int p2,int k){     if(tr[p1].l==tr[p1].r)     {          if(tr[p2].s-tr[p1].s>k)               return tr[p1].l;          return 0;     }     else     {          int tmp=tr[tr[p2].ll].s-tr[tr[p1].ll].s;          if(tmp>k)               return find(tr[p1].ll,tr[p2].ll,k);          return find(tr[p1].rr,tr[p2].rr,k);     }}int main(){     int n,m,lim;     scanf("%d%d",&n,&lim);     int i;     for(i=1;i<=n;i++)     {          scanf("%d",&a[i].x);          a[i].t=i;     }     sort(a+1,a+1+n);     int px=1;     f[px]=a[1].x;     fx[a[1].t]=px;     for(i=2;i<=n;i++)     {          if(a[i].x!=a[i-1].x)               px++;          f[px]=a[i].x;          fx[a[i].t]=px;     }     tot++;     pl[0]=tot;     build(1,px);     for(i=1;i<=n;i++)     {       pl[i]=tot+1;          add(pl[i-1],fx[i],fx[i],1);     }     int s,t;     scanf("%d",&m);     for(i=1;i<=m;i++)     {          scanf("%d%d",&s,&t);          int xt=f[find(pl[s-1],pl[t],(t-s+1)/2)];          if(xt==0)               printf("no\n");          else               printf("yes %d\n",xt);     }     return 0;}


0 0