zoukankan      html  css  js  c++  java
  • [Luogu 1533] 可怜的狗狗

    <题目链接>

    平衡树,我用的SBT。

    排一下序尽量减少操作次数。

    第K大询问。

    以及插入删除。

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int MAXN=300010,MAXM=50010;
    int n,m,x,y,a[MAXN],ans[MAXN];
    struct Query
    {
    	int l,r,k,index;
    	bool operator <(const Query &rhs) const
    	{
    		return l<rhs.l ? 1 : (l<rhs.l ? 0 : r<rhs.r);
    	}
    }q[MAXM];
    class SBT
    {
    	public:
    		int rt;
    		SBT(void)
    		{
    			rt=cnt=0;
    			memset(s,0,sizeof s);
    		}
    		void Insert(int &i,int x)
    		{
    			if(!i)
    			{
    				s[i=++cnt].v=x,s[i].size=1;
    				return;
    			}
    			++s[i].size;
    			bool t=x>s[i].v;
    			Insert(s[i].c[t],x);
    			Maintain(i,t);
    		}
    		void Erase(int &i,int x)
    		{
    			--s[i].size;
    			if(x==s[i].v)
    				if(s[i].c[0] && s[i].c[1])
    				{
    					int t=s[i].c[1];
    					while(s[t].c[0])
    						t=s[t].c[0];
    					s[i].v=s[t].v;
    					Erase(s[i].c[1],s[t].v);
    				}
    				else
    					i=s[i].c[0] | s[i].c[1];
    			else
    				Erase(s[i].c[x>s[i].v],x);
    		}
    		int Xth(int i,int x)
    		{
    			int t=s[s[i].c[0]].size+1;
    			if(x<t)
    				return Xth(s[i].c[0],x);
    			else if(x>t)
    				return Xth(s[i].c[1],x-t);
    			else
    				return s[i].v;
    		}
    	private:
    		int cnt;
    		struct node
    		{
    			int v,size,c[2];
    		}s[MAXN];
    		void Update(int i)
    		{
    			s[i].size=s[s[i].c[0]].size+s[s[i].c[1]].size+1;
    		}
    		void Rotate(int &i,bool p)
    		{
    			int t=s[i].c[!p];
    			s[i].c[!p]=s[t].c[p],s[t].c[p]=i;
    			Update(i),Update(i=t);
    		}
    		void Maintain(int &i,bool p)
    		{
    			int t=s[s[i].c[!p]].size;
    			if(t<s[s[s[i].c[p]].c[p]].size)
    				Rotate(i,!p);
    			else if(t<s[s[s[i].c[p]].c[!p]].size)
    				Rotate(s[i].c[p],p),Rotate(i,!p);
    			else
    				return;
    			Maintain(s[i].c[0],0);
    			Maintain(s[i].c[1],1);
    			Maintain(i,0);
    			Maintain(i,1);
    		}
    }T;
    int main(int argc,char *argv[])
    {
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&a[i]);
    	for(int i=1;i<=m;++i)
    	{
    		scanf("%d %d %d",&q[i].l,&q[i].r,&q[i].k);
    		q[i].index=i;
    	}
    	sort(q+1,q+m+1);
    	x=1;
    	for(int i=1,&rt=T.rt;i<=m;++i)
    	{
    		while(y<q[i].r)
    			T.Insert(rt,a[++y]);
    		while(x<q[i].l)
    			T.Erase(rt,a[x++]);
    		ans[q[i].index]=T.Xth(rt,q[i].k);
    	}
    	for(int i=1;i<=m;++i)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    多线程
    python 进程间通信
    python 生产者消费者模型
    多线程锁
    io多路复用(三)
    div 加滚动条的方法
    10矩形覆盖
    11.二进制中1的个数
    12数值的整数次方
    9 变态跳台阶
  • 原文地址:https://www.cnblogs.com/Capella/p/8134242.html
Copyright © 2011-2022 走看看