bzoj 3524: [Poi2014]Couriers

来源:互联网 发布:淘宝店铺装修哪家好 编辑:程序博客网 时间:2024/04/29 05:01

Description

给一个长度为n的序列a。1≤a[i]≤n。
m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

Input

第一行两个数n,m。
第二行n个数,a[i]。
接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

Output

m行,每行对应一个答案。

Sample Input

7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6

Sample Output

1
0
3
0
4

HINT

【数据范围】

n,m≤500000


和2223是双倍经验。

直接上主席树用区间k大做法做就行了。

可是我的主席树直接被卡内存了。连左右端点都不能记录。。= =b

#include<cstdio>#include<algorithm>using namespace std;struct tree{     int ll,rr;     int s;}tr[10000001];int tot;struct number{     int x,t;}a[500001];inline bool cmp(number x,number y){     if(x.x<y.x)          return true;     return false;}int f[500001],fx[500001];int pl[500001];inline void build(int l,int r){     int p=tot;     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 loc,int x){ if(p==0)      return 0;     if(l==r)     {          tot++;          tr[tot].s=tr[p].s+x;          return tot;     }     else     {          int mid=(l+r)/2;          tot++;          int pp=tot;          if(loc<=mid)               tr[pp].ll=add(tr[p].ll,l,mid,loc,x);          else               tr[pp].ll=tr[p].ll;          if(loc>mid)               tr[pp].rr=add(tr[p].rr,mid+1,r,loc,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,int l,int r){     if(l==r)     {          if(tr[p2].s-tr[p1].s>k)               return l;          return 0;     }     else     {       int mid=(l+r)/2;          int tmp=tr[tr[p2].ll].s-tr[tr[p1].ll].s;          if(tmp>k)               return find(tr[p1].ll,tr[p2].ll,k,l,mid);          return find(tr[p1].rr,tr[p2].rr,k,mid+1,r);     }}int main(){     int n,m;     scanf("%d%d",&n,&m);     int i;     for(i=1;i<=n;i++)     {          scanf("%d",&a[i].x);          a[i].t=i;     }     sort(a+1,a+1+n,cmp);     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],1,px,fx[i],1);     }     int s,t;     for(i=1;i<=m;i++)     {          scanf("%d%d",&s,&t);          printf("%d\n",f[find(pl[s-1],pl[t],(t-s+1)/2,1,px)]);     }     return 0;}


0 0
原创粉丝点击