码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3524: [Poi2014]Couriers

时间:2017-12-15 21:34:40      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:div   query   bsp   代码   printf   输出   content   while   open   

3524: [Poi2014]Couriers

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


2016.7.9重设空间,但未重测!

/*
    主席树处理+二分查找
    几乎是个模板题,代码很短。
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 500010
using namespace std;
int tot,cnt,n,m,root[maxn];
int lc[maxn*20],rc[maxn*20],sum[maxn*20];
void build(int x,int &y,int l,int r,int v){
    tot++;y=tot;
    sum[y]=sum[x]+1;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(v<=mid){
        rc[y]=rc[x];
        build(lc[x],lc[y],l,mid,v);
    }
    else{
        lc[y]=lc[x];
        build(rc[x],rc[y],mid+1,r,v);
    }
}
int query(int x,int y){//两个时刻 
    int l=1,r=n,tmp=(y-x+1)/2;
    x=root[x-1];y=root[y];
    while(l!=r){
        if(sum[y]-sum[x]<=tmp)return 0;
        int mid=l+r>>1;
        if(sum[lc[y]]-sum[lc[x]]>tmp){
            r=mid;x=lc[x];y=lc[y];
        }
        else if(sum[rc[y]]-sum[rc[x]]>tmp){
            l=mid+1;x=rc[x];y=rc[y];
        }
        else return 0;
    }
    return l;
}
int main(){
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        build(root[i-1],root[i],1,n,x);
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        printf("%d\n",query(x,y));
    }
}

 

/*
    递归查询
    注意不要把if(l==r)return l;写成
    if(l==r){
        if(sum[l]>k)return l;
        else return 0;
    }
    因为l不是线段树下标,而是区间边界
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 500010
using namespace std;
int tot,cnt,n,m,root[maxn];
int lc[maxn*20],rc[maxn*20],sum[maxn*20];
void build(int x,int &y,int l,int r,int v){
    tot++;y=tot;
    sum[y]=sum[x]+1;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(v<=mid){
        rc[y]=rc[x];
        build(lc[x],lc[y],l,mid,v);
    }
    else{
        lc[y]=lc[x];
        build(rc[x],rc[y],mid+1,r,v);
    }
}
int query(int x,int y,int l,int r,int k){
    if(l==r)return l;
    int mid=(l+r)>>1;
    int sz=sum[y]-sum[x];
    if(sz<=k)return 0;
    if(sum[lc[y]]-sum[lc[x]]>k)return query(lc[x],lc[y],l,mid,k);
    if(sum[rc[y]]-sum[rc[x]]>k)return query(rc[x],rc[y],mid+1,r,k);
    return 0;
}
int main(){
    freopen("Cola.txt","r",stdin);
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        build(root[i-1],root[i],1,n,x);
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        printf("%d\n",query(root[x-1],root[y],1,n,(y-x+1)/2));
    }
}

 

 

bzoj3524: [Poi2014]Couriers

标签:div   query   bsp   代码   printf   输出   content   while   open   

原文地址:http://www.cnblogs.com/thmyl/p/8044723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!