zoukankan      html  css  js  c++  java
  • bzoj 2770 YY的Treap

    Written with StackEdit.

    Description

    志向远大的(YY)小朋友在学完快速排序之后决定学习平衡树,左思右想再加上(SY)的教唆,(YY)决定学习(Treap)。友爱教教父(SY)如砍瓜切菜般教会了(YY)小朋友(Treap)一种平衡树,通过对每个节点随机分配一个priority,同时保证这棵平衡树关于priority是一个小根堆以保证效率)。这时候不怎么友爱的(510)跑了出来,他问了(YY)小朋友一个极不和谐的问题:怎么求(Treap)中两个点之间的路径长度(YY)秒了之后决定把这个问题交给你来做,但只要求出树中两点的(LCA)

    Input

    第一行两个整数(n,m.)

    第二行(n)个整数表示每个元素的(key.)

    第三行(n)个整数表示每个元素的(priority.)

    接下(m)行,每行一条命令,

    (I) (A) (B),插入一个元素,(key)(A,priority)(B.)

    (D) (A),删除一个元素,(key)(A).

    (Q) (A) (B),询问(key)分别为(A)(B)(LCA)(key.)

    Output

    对于每个(Q)输出一个整数。

    Sample Input

    2 2
    1 2
    4 5
    Q 1 2
    I 3 3

    Sample Output

    1

    HINT

    数据保证(n<=10^5,m<=3*10^5).

    其余整数均不超过(int)的范围.

    数据保证任意时刻树中(key)(priority)均不相同.

    Solution

    • 此题就是对(treap)基本性质的一个考察.
    • (C)(A,B)(LCA)(假设(key_a<key_b)).需要满足(key_cin [key_a,key_b]),这样能保证(A,B)到根的路径上都经过(C).
    • 而要求最近的公共祖先,根据(priority)满足小根堆的性质,只需找出其中(priority)最小的点即为(LCA).
    • 可以建一颗权值线段树,问题转化为修改,删除,以及区间上查询最值.
    #include<bits/stdc++.h> 
    #define inf 0x7fffffff
    #define root Tree[o]
    #define lson Tree[o<<1]
    #define rson Tree[o<<1|1]
    using namespace std;
    typedef long long LoveLive;
    typedef pair<int,int> pii;
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		{
    			fh=-1;
    			jp=getchar();
    		}
    	while (jp>='0'&&jp<='9')
    		{
    			out=out*10+jp-'0';
    			jp=getchar();
    		}
    	return out*fh;
    }
    const int MAXN=4e5+10;
    int n,m;
    struct Query{
    	int op;
    	int a,b;//key,pro
    	int ans,id;
    }q[MAXN];
    int kc[MAXN];
    struct node{
    	int l,r,mi,pos,sum,val;
    }Tree[MAXN<<3];
    void phup(int o)
    {
    	if(lson.mi<rson.mi)
    		root.mi=lson.mi,root.pos=lson.pos;
    	else
    		root.mi=rson.mi,root.pos=rson.pos;
    	root.sum=lson.sum+rson.sum;
    }
    void bd(int l,int r,int o)
    {
    	int mid=(l+r)>>1;
    	root.l=l,root.r=r;
    	root.mi=inf;
    	root.sum=0;
    	if(l==r)
    		return;
    	bd(l,mid,o<<1);
    	bd(mid+1,r,o<<1|1);
    }
    void add(int o,int x,int pos)
    {
    	int l=root.l,r=root.r;
    	int mid=(l+r)>>1;
    	if(l==r)
    		{
    			root.val=x;
    			root.mi=x;
    			root.pos=l;
    			++root.sum;
    			return;
    		}
    	if(pos<=mid)
    		add(o<<1,x,pos);
    	else
    		add(o<<1|1,x,pos);
    	phup(o);
    }
    void del(int o,int pos)
    {
    	int l=root.l,r=root.r;
    	int mid=(l+r)>>1;
    	if(l==r)
    		{
    			root.mi=inf;
    			--root.sum;
    			return;
    		}
    	if(pos<=mid)
    		del(o<<1,pos);
    	else
    		del(o<<1|1,pos);
    	phup(o);
    }
    void ins(int x,int pos)
    {
    	add(1,x,pos);
    }
    void rem(int pos)
    {
    	del(1,pos);
    }
    int ansmi,anspos;
    void qy(int o,int L,int R)
    {
    	int l=root.l,r=root.r;
    	int mid=(l+r)>>1;
    	if(r<L || l>R)
    		return;
    	if(L<=l && r<=R)
    		{
    			if(root.mi<ansmi)
    				ansmi=root.mi,anspos=root.pos;
    			return;
    		}
    	if(L<=mid)
    		qy(o<<1,L,R);
    	if(R>mid)
    		qy(o<<1|1,L,R);
    }
    int main()
    {
    	n=read(),m=read();
    	int cnt=0;
    	for(int i=1;i<=n;++i)
    		{
    			q[i].op=1;
    			q[i].a=read();
    			kc[++cnt]=q[i].a;
    			q[i].id=i;
    		}
    	for(int i=1;i<=n;++i)
    		q[i].b=read();
    	int idx=n;
    	for(int i=1;i<=m;++i)
    		{
    			++idx;
    			q[idx].id=idx;
    			char buf[2];
    			scanf("%s",buf);
    			if(buf[0]=='I')
    				{
    					q[idx].op=1;
    					q[idx].a=read();
    					kc[++cnt]=q[idx].a;
    					q[idx].b=read();
    				}
    			else if(buf[0]=='D')
    				{
    					q[idx].op=2;
    					q[idx].a=read();
    					kc[++cnt]=q[idx].a;
    				}
    			else
    				{
    					q[idx].op=3;
    					q[idx].a=read();
    					kc[++cnt]=q[idx].a;
    					q[idx].b=read();
    					kc[++cnt]=q[idx].b;
    				}
    		}
    	bd(1,2*n,1);
    	sort(kc+1,kc+1+cnt);
    	cnt=unique(kc+1,kc+1+cnt)-(kc+1);
    	for(int i=1;i<=idx;++i)
    		{
    			if(q[i].op==1)
    				{
    					q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
    					ins(q[i].b,q[i].a);	
    				}
    			else if(q[i].op==2)
    				{
    					q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
    					rem(q[i].a);
    				}
    			else if(q[i].op==3)
    				{
    					 q[i].a=lower_bound(kc+1,kc+1+cnt,q[i].a)-kc;
    					 q[i].b=lower_bound(kc+1,kc+1+cnt,q[i].b)-kc;
    					 ansmi=inf;
    					 qy(1,min(q[i].a,q[i].b),max(q[i].a,q[i].b));
    					 printf("%d
    ",kc[anspos]);
    				}
    		}
    	return 0;
    }
    
  • 相关阅读:
    抓鱼社区
    DotNetTextBox V3.0 所见即所得编辑器控件Ver3.3.3 Free(免费版)
    Pet Shop 4.0系统
    北大青鸟PPT/ Net学习课件/asp.net,AJAX,ADO.net视频教程
    [开源]ASP.NET通用权限管理系统(FrameWork) 1.0.1 Release
    sql isnull函数
    几种常见算法的介绍及复杂度分析(转)
    ajaxpro配置与使用
    C#对图片的几种简单处理
    [你必须知道的.NET] 开篇有益
  • 原文地址:https://www.cnblogs.com/jklover/p/10126898.html
Copyright © 2011-2022 走看看