zoukankan      html  css  js  c++  java
  • 【刷题】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='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(c!='')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),'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    View.VISIBLE、INVISIBLE、GONE的区别
    Android中TextView内容过长加省略号
    Android 读取SIM卡参数
    java分布式通信系统(J2EE分布式服务器架构)
    Java分布式处理技术(RMI,JDNI)
    Java分布式缓存框架
    spring
    Apache与Nginx的优缺点比较
    Java如何获取文件编码格式
    java 乱码问题-Dfile.encoding=UTF-8
  • 原文地址:https://www.cnblogs.com/hongyj/p/8594577.html
Copyright © 2011-2022 走看看