• 【题解】Luogu P1533 可怜的狗狗


    原题传送门

    莫队介绍,Splay介绍

    离线的题目,莫队是不错的解决方法

    先把询问排一下序

    剩下就套一个莫队的板子

    每来一只狗就把漂亮值插入平衡树

    每去掉一只狗就把漂亮值从平衡树中删掉

    每次查询查平衡树中第k小

    #pragma GCC optimize("O3")
    #include <bits/stdc++.h>
    #define N 800005
    #define M 50005
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf; 
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    }
    inline int read()
    {
        register int x=0,f=1;register char ch=nc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=nc();
        return x*f;
    }
    inline void write(register int x)
    {
        if(!x)putchar('0');if(x<0)x=-x,putchar('-');
        static int sta[20];register int tot=0;
        while(x)sta[tot++]=x%10,x/=10;
        while(tot)putchar(sta[--tot]+48);
    }
    struct Splay{
    	int v,fa,ch[2],sum,rec;
    }tree[N];
    int tot=0;
    inline void update(register int x)
    {
    	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;
    }
    inline bool findd(register int x)
    {
    	return tree[tree[x].fa].ch[0]==x?0:1;
    }
    inline void connect(register int x,register int fa,register int son)
    {
    	tree[x].fa=fa;
    	tree[fa].ch[son]=x;
    } 
    inline void rotate(register int x)
    {
    	int Y=tree[x].fa;
    	int R=tree[Y].fa;
    	int Yson=findd(x);
    	int Rson=findd(Y);
    	int B=tree[x].ch[Yson^1];
    	connect(B,Y,Yson);
    	connect(Y,x,Yson^1);
    	connect(x,R,Rson);
    	update(Y),update(x);
    }
    inline void splay(register int x,register int to)
    {
    	to=tree[to].fa;
    	while(tree[x].fa!=to)
    	{
    		int y=tree[x].fa;
    		if(tree[y].fa==to)
    			rotate(x);
    		else if(findd(x)==findd(y))
    			rotate(y),rotate(x);
    		else
    			rotate(x),rotate(x);
    	}	
    }
    inline int newpoint(register int v,register int fa)
    {
    	tree[++tot].fa=fa;
    	tree[tot].v=v;
    	tree[tot].sum=tree[tot].rec=1;
    	return tot; 
    }
    inline void Insert(register int x)
    {
    	int now=tree[0].ch[1];
    	if(tree[0].ch[1]==0)
    	{
    		newpoint(x,0);
    		tree[0].ch[1]=tot;
    	}
    	else
    	{
    		while(19260817)
    		{
    			++tree[now].sum;
    			if(tree[now].v==x)
    			{
    				++tree[now].rec;
    				splay(now,tree[0].ch[1]);
    				return;
    			}
    			int nxt=x<tree[now].v?0:1;
    			if(!tree[now].ch[nxt])
    			{
    				int p=newpoint(x,now);
    				tree[now].ch[nxt]=p;
    				splay(p,tree[0].ch[1]);
    				return;
    			}
    			now=tree[now].ch[nxt];
    		}
    	}
    }
    inline int find(register int v)
    {
    	int now=tree[0].ch[1];
    	while(19260817)
    	{
    		if(tree[now].v==v)
    		{
    			splay(now,tree[0].ch[1]);
    			return now;
    		}
    		int nxt=v<tree[now].v?0:1;
    		if(!tree[now].ch[nxt])
    			return 0;
    		now=tree[now].ch[nxt];
    	}
    }
    inline void delet(register int x)
    {
    	int pos=find(x);
    	if(!pos)
    		return;
    	if(tree[pos].rec>1)
    	{
    		--tree[pos].rec;
    		--tree[pos].sum;
    	}
    	else
    	{
    		if(!tree[pos].ch[0]&&!tree[pos].ch[1])
    			tree[0].ch[1]=0;
    		else if(!tree[pos].ch[0])
    		{
    			tree[0].ch[1]=tree[pos].ch[1];
    			tree[tree[0].ch[1]].fa=0;
    		}
    		else
    		{
    			int left=tree[pos].ch[0];
    			while(tree[left].ch[1])
    				left=tree[left].ch[1];
    			splay(left,tree[pos].ch[0]);
    			connect(tree[pos].ch[1],left,1);
    			connect(left,0,1);
    			update(left);
    		}
    	}
    }
    inline int arank(register int x)
    {
    	int now=tree[0].ch[1];
    	while(19260817)
    	{
    		int used=tree[now].sum-tree[tree[now].ch[1]].sum;
    		if(x>tree[tree[now].ch[0]].sum&&x<=used)
    		{
    			splay(now,tree[0].ch[1]);
    			return tree[now].v;
    		}
    		if(x<used)
    			now=tree[now].ch[0];
    		else
    			x-=used,now=tree[now].ch[1];
    	}
    }
    struct query{
    	int l,r,id,bl,k;
    }q[M];
    int a[N],blocksize=0,ans[M];
    inline bool cmp(register query a,register query b)
    {
    	return a.bl!=b.bl?a.l<b.l:((a.bl&1)?a.r<b.r:a.r>b.r);
    }
    int main()
    {
    	int n=read(),m=read();
    	blocksize=sqrt(m);
    	for(register int i=1;i<=n;++i)
    		a[i]=read();
    	for(register int i=1;i<=m;++i)
    	{
    		int l=read(),r=read(),k=read();
    		q[i]=(query){l,r,i,l/blocksize,k};
    	}
    	sort(q+1,q+m+1,cmp);
    	int l=1,r=0;
    	for(register int i=1;i<=m;++i)
    	{
    		int ll=q[i].l,rr=q[i].r;
    		while(ll<l)
    			Insert(a[--l]);
    		while(rr>r)
    			Insert(a[++r]);
    		while(ll>l)
    			delet(a[l++]);
    		while(rr<r)
    			delet(a[r--]);
    		ans[q[i].id]=arank(q[i].k);
    	}
    	for(register int i=1;i<=m;++i)
    		write(ans[i]),puts("");
    	return 0;
    }
    
  • 相关阅读:
    运算符
    java--有关前台展示图片流的用法
    TortoiseSVN--Subversion客户端使用详解及问题解决
    SVN 文件的解锁方法
    JDBC中获取数据表的信息
    tomcat配置文件解决乱码问题
    正则表达式常用匹配
    Java:如何选择最为合适的Web开发框架
    键盘enter事件 兼容FF和IE和Opera
    PayPal 支付接口详解
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10015943.html
Copyright © 2020-2023  润新知