刷题BZOJ 3524 [Poi2014]Couriers

Posted oyiya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题BZOJ 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

Solution

维护数字出现次数——主席树
同样用主席树维护\(sum\)
每次查询的时候选择满足条件的往下走就行了
因为一段数列中出现次数大于一半的至多只会有一个,所以这样暴力做的复杂度是正确的

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
#define Mid ((l+r)>>1)
#define lson l,Mid
#define rson Mid+1,r
const int MAXN=500000+10;
int n,m,A[MAXN];
std::vector<int> V;
std::map<int,int> M;
struct ChairMan_Tree{
    int cnt,lc[MAXN<<5],rc[MAXN<<5],sum[MAXN<<5],root[MAXN];
    inline void init()
    {
        cnt=0;
        memset(lc,0,sizeof(lc));
        memset(rc,0,sizeof(rc));
        memset(sum,0,sizeof(sum));
    }
    inline void Build(int &rt,int l,int r)
    {
        rt=++cnt;
        sum[rt]=0;
        if(l==r)return ;
        Build(lc[rt],lson);
        Build(rc[rt],rson);
    }
    inline void Insert(int &rt,int l,int r,int last,int pos)
    {
        rt=++cnt;
        sum[rt]=sum[last]+1;
        lc[rt]=lc[last];
        rc[rt]=rc[last];
        if(l==r)return ;
        else
        {
            if(pos<=Mid)Insert(lc[rt],lson,lc[last],pos);
            else Insert(rc[rt],rson,rc[last],pos);
        }
    }
    inline int Query(int now,int last,int l,int r,int k)
    {
        if(sum[now]-sum[last]<=k)return 0;
        if(l==r)return l;
        else
        {
            if(sum[lc[now]]-sum[lc[last]]>k)return Query(lc[now],lc[last],lson,k);
            else return Query(rc[now],rc[last],rson,k);
        }
    }
};
ChairMan_Tree T;
template<typename T> inline void read(T &x)
{
    T data=0,w=1;
    char ch=0;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void discre()
{
    sort(V.begin(),V.end());
    V.erase(unique(V.begin(),V.end()),V.end());
    for(register int i=1;i<=n;++i)
    {
        int pre=A[i];
        A[i]=lower_bound(V.begin(),V.end(),A[i])-V.begin()+1;
        M[A[i]]=pre;
    }
}
int main()
{
    read(n);read(m);
    for(register int i=1;i<=n;++i)
    {
        read(A[i]);
        V.push_back(A[i]);
    }
    discre();
    T.init();
    T.Build(T.root[0],1,n);
    for(register int i=1;i<=n;++i)T.Insert(T.root[i],1,n,T.root[i-1],A[i]);
    while(m--)
    {
        int l,r;
        read(l);read(r);
        write(T.Query(T.root[r],T.root[l-1],1,n,(r-l+1)/2),'\n');
    }
    return 0;
}

以上是关于刷题BZOJ 3524 [Poi2014]Couriers的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ2223][BZOJ3524][Poi2014]Couriers 主席树

bzoj3524 [POI2014]Couriers

bzoj3524[Poi2014]Couriers*

bzoj3524: [Poi2014]Couriers

BZOJ3524: [Poi2014]Couriers

bzoj3524/2223 [Poi2014]Couriers