BZOJ3524:[POI2014]Couriers


On the Chairman tree: https: //www.cnblogs.com/AKMer/p/9956734.html

Topic portal: https: //www.lydsy.com/JudgeOnline/problem.php id = 3524?

Assuming that the number of columns not give you a start, but once again modify operation allows you to insert the value xx, and ask ask you to insert the L th Inter R operations, there is no value more than the number of insertions (R-L +1) / 2, the meaning of the questions such a transformation, it is easy to write a Chairman tree.

We can build on the range Chairman tree, each node within the statistical range of digital [l, r] of how many. So just use the Chairman of the tree r th edition of cnt cnt minus l-1 the first version of the Chairman of the tree, is the operating [L, R] is inserted in how many numbers in the range [l, r] of. If [l, mid] is greater than the number of (R-L + 1) / 2 in the answer [l, mid], the answer is determined to be the same reason the [mid + 1, r] inside, if not satisfied, then there is no such value directly back to 0 on the line.

Time complexity: O ((n + m) logn)
space complexity: O (nlogn)

#include <cstdio>
using namespace std;

const int maxn=5e5+5;

int n,m;
int rt[maxn];

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

struct tree_node 
{
    int cnt,ls,rs;
};

struct Chairman_tree 
{
    int tot;
    tree_node tree[maxn*20];
    
    void ins(int lst,int &now,int l,int r,int pos) 
	{
        now=++tot;
		tree[now]=tree[lst];
		tree[now].cnt++;// first son all information about inherited, then the interval plus a number of digits 
        if (l == r) return;
        int mid = (l + r)
        if(pos<=mid)
		   ins(tree[lst].ls,tree[now].ls,l,mid,pos);//新建左儿子
        else 
		    ins(tree[lst].rs,tree[now].rs,mid+1,r,pos);//新建右儿子
    }
    
    int query(int L,int R,int l,int r,int limit)
	 {
        if(l==r) 
		{
            if(tree[R].cnt-tree[L].cnt>limit)return l;//记得判断
            else return 0;
        }
        int mid=(l+r)>>1;
        int tmp1=tree[tree[R].ls].cnt-tree[tree[L].ls].cnt;
        int tmp2=tree[tree[R].rs].cnt-tree[tree[L].rs].cnt;
        if(tmp1>limit)return query(tree[L].ls,tree[R].ls,l,mid,limit);
        if(tmp2>limit)return query(tree[L].rs,tree[R].rs,mid+1,r,limit);
        return 0;//同题解所述
    }
}T;

int main() {
    n=read(),m=read();
    for(int i=1;i<=n;i++) 
	{
        int x=read();
        T.ins(rt[i-1],rt[i],1,n,x);
		//rt[i]表示第i个版本的主席树
    }
    for(int i=1;i<=m;i++) 
	{
        int l=read(),r=read(),limit=(r-l+1)>>1;
        int ans=T.query(rt[l-1],rt[r],1,n,limit);
        printf("%d\n",ans);
    }
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/cutemush/p/11804284.html