zoukankan      html  css  js  c++  java
  • 【NOIP2017】列队(Splay)

    【NOIP2017】列队(Splay)

    题面

    洛谷

    题解

    其实好简单啊。。。
    对于每一行维护一棵(Splay)
    对于最后一列维护一棵(Splay)
    (Splay)上一个节点表示一段区间
    每次出去一个人就是把当前的(Splay)的一个节点拆分成(3)

    然后就很简单了。。
    细节比较多。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 2000000
    #define ls (t[x].ch[0])
    #define rs (t[x].ch[1])
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Node
    {
    	int ch[2],ff;
    	ll size;
    	ll l,r;
    }t[MAX];
    int tot;
    int n,m,Q;
    struct SplayTree
    {
    	int root;
    	int Node(ll l,ll r){++tot;t[tot].l=l;t[tot].r=r;t[tot].size=r-l;return tot;}
    	void pushup(int x){t[x].size=t[ls].size+t[rs].size+t[x].r-t[x].l;}
    	void rotate(int x)
    	{
    		int y=t[x].ff,z=t[y].ff;
    		int k=t[y].ch[1]==x;
    		if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
    		t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;
    		t[x].ch[k^1]=y;t[y].ff=x;
    		pushup(y);pushup(x);
    	}
    	void Splay(int x)
    	{
    		for(int y=t[x].ff;y;rotate(x),y=t[x].ff)
    			if(t[y].ff)(rand()&1)?rotate(x):rotate(y);
    		root=x;
    	}
    	int Split(int x,ll K)
    	{
    		K+=t[x].l;
    		int y=Node(K,t[x].r);t[x].r=K;
    		if(!rs)t[y].ff=x,rs=y;
    		else
    		{
    			int u=rs;
    			while(t[u].ch[0])u=t[u].ch[0];
    			t[y].ff=u;t[u].ch[0]=y;
    		}
    		Splay(y);return y;
    	}
    	ll DelKth(ll K)
    	{
    		int x=root;
    		while(2333)
    		{
    			if(K<=t[ls].size)x=ls;
    			else
    			{
    				K-=t[ls].size;
    				if(K<=t[x].r-t[x].l)
    				{
    					if(K<t[x].r-t[x].l)Split(x,K);
    					if(K>1)x=Split(x,K-1);
    					break;
    				}
    				else K-=t[x].r-t[x].l,x=rs;
    			}
    		}
    		Splay(x);t[ls].ff=t[rs].ff=0;
    		if(!ls)root=rs;
    		else
    		{
    			int y=ls;
    			while(t[y].ch[1])y=t[y].ch[1];
    			Splay(y);
    			root=t[t[y].ch[1]=t[x].ch[1]].ff=y;
    			pushup(y);
    		}
    		return t[x].l;
    	}
    	void Insert(ll k)
    	{
    		int y=Node(k,k+1);
    		if(!root)root=y;
    		else
    		{
    			int x=root;
    			while(rs)x=rs;
    			Splay(x);
    			t[rs=y].ff=x;pushup(x);
    		}
    	}
    }Splay[MAX];
    int main()
    {
    	n=read();m=read();Q=read();
    	for(int i=1;i<=n;++i)Splay[i].root=Splay[i].Node(1ll*i*m-m+1,1ll*i*m);
    	for(int i=1;i<=n;++i)Splay[0].Insert(1ll*i*m);
    	while(Q--)
    	{
    		int x=read(),y=read();ll ans;
    		Splay[x].Insert(Splay[0].DelKth(x));
    		printf("%lld
    ",ans=Splay[x].DelKth(y));
    		Splay[0].Insert(ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    poj 2488 DFS
    畅通工程 并查集模版
    KMP 模板
    poj 1426 DFS
    poj 2528 线段数
    poj 3468 线段数 修改区间(点)
    CVPR2012文章阅读(2)A Unified Approach to Salient Object Detection via Low Rank Matrix Recovery
    如何制定目标
    Saliency Map 最新综述
    计算机视觉模式识别重要会议杂志
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8684116.html
Copyright © 2011-2022 走看看