• jzoj 4811. 【NOIP2016提高A组五校联考1】排队


    Question

    在这里插入图片描述

    Solution

    考后听别人打得都是什么树剖,线段树,堆。。。
    感觉自己打的个链表有点虚啊。。。
    我们先弄一个后序遍历,将其中的每一位指向它的下一位,设为to[i]to[i]
    我们设laslas表示后序遍历中最前的未被标记的点的位置。

    操作一:

    我们只需跳x次并将每个位置都标记一下即可。并将laslas更新。
    输出跳到最后的位置。

    操作二:

    我们用倍增跳到它的最远的标记过的祖先。
    将这个标记删除,设这个位置为kk
    如果k<lask<las,就将to[k]=lasto[k]=las,并将laslas改成kk即可。
    如果k>lask>las,我们就用另一个变量(设为oo)跳到一个位置,使得to[o]>kto[o]>k
    就将to[k]=to[o],to[o]=kto[k]=to[o],to[o]=k即可。
    输出祖先的深度减去输入的x的深度即可。

    Code

    #include<cstdio>
    #include<algorithm>
    #define N 100010
    using namespace std;
    struct node{int u,v;}e[N<<1];
    int n,T,e1[N],e2[N],now,dep[N],hav[N],to[N];
    int fa[N][17],s=0,dfn[N],fr[N],tot=0,las=1;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    int cmp(node x,node y) {return x.u==y.u ? x.v<y.v : x.u<y.u;}
    
    void dfs(int x)
    {
    	if (!e2[x]) {dfn[++tot]=x; fr[x]=tot; return;}
    	for (int p=e1[x],v;p<=e2[x];p++)
    	{
    		v=e[p].v;
    		if (v==fa[x][0]) continue;
    		dep[v]=dep[x]+1,fa[v][0]=x,dfs(v);
    	}
    	dfn[++tot]=x;
    	fr[x]=tot;
    }
    
    int main()
    {
    	n=read(),T=read();to[0]=1;to[n]=n+1;
    	for (int i=1;i<n;i++)
    	{
    		e[(i<<1)-1].u=read(),e[(i<<1)-1].v=read();
    		e[i<<1].v=e[(i<<1)-1].u,e[i<<1].u=e[(i<<1)-1].v;
    		to[i]=i+1;
    	}
    	sort(e+1,e+n+n-1,cmp);
    	e1[e[1].u]=1;
    	for (int i=2;i<=n+n-2;i++)
    		if (e[i].u!=e[i-1].u)
    			e2[e[i-1].u]=i-1,e1[e[i].u]=i;
    	e2[e[n+n-2].u]=n+n-2;
    	dfs(1);
    	for (int j=1;j<=16;j++)
    		for (int i=1;i<=n;i++)
    			fa[i][j]=fa[fa[i][j-1]][j-1];
    	for (int i=1,opt,x;i<=T;i++)
    	{
    		opt=read(),x=read();
    		if (opt==1)
    		{
    			now=las;hav[now]=1;x--;
    			while (x--) now=to[now],hav[now]=1;
    			las=to[now];printf("%d
    ",dfn[now]);
    		}
    		else
    		{
    			s=dep[x];
    			for (int j=16;j>=0;j--)
    				if (hav[fr[fa[x][j]]]) x=fa[x][j];
    			if (fr[x]<las) to[fr[x]]=las,las=fr[x];
    			else
    			{
    				now=las;
    				while (to[now]<fr[x]) now=to[now];
    				to[fr[x]]=to[now],to[now]=fr[x];
    			}
    			hav[fr[x]]=0;
    			printf("%d
    ",s-dep[x]);
    		}
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    Python学习资料
    异常
    I/O
    Python3+迭代器与生成器
    python标准数据类型
    人工智能、机器学习和深度学习
    原地排序和复制排序
    序列化和Json
    登陆加密小程序
    hashlib模块加密用法
  • 原文地址:https://www.cnblogs.com/jz929/p/11817525.html
Copyright © 2020-2023  润新知