zoukankan      html  css  js  c++  java
  • P3233 [HNOI2014]世界树

    这是一道有趣的题!

    第一眼:建虚树然后 DP?好麻烦。

    第二眼:将临时议事所按照深度排序,接着按顺序从小到大覆盖,傻逼题。

    第三眼:怎么判断覆盖的结点当前属于哪个临时议事所啊,这不是要求距离当前临时议事所最近的已经做过的临时议事所吗,我是傻逼。

    第四眼:用数据结构维护?码量有点大不想写!

    第五眼:在按照深度从小到大排序的同时以编号为第二关键字从小到大排序。这样在虚树上向上跳,遇到没有标记过的结点就标记,标记过的就直接不做了。保证了复杂度,也不用什么数据结构啦。

    至于证明,显然排序后到当前临时议事所管辖的一定是向上到某个结点的整个子树。

    讲得有点简略,多画图就是了。

    时间复杂度 (Oleft(nlog n ight))

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define N 300005
    #define NN 600005
    #define For(i,x,y)for(i=x;i<=(y);i++)
    #define Down(i,x,y)for(i=x;i>=(y);i--)
    struct node
    {
    	int next,to;
    }e[NN];
    bool type[N];
    int fa[N][20],h[NN],head[N],bin[N],last[N],ans[N],dfn[N],col[N],id[N],dep[N],siz[N],g,cnt;
    int read()
    {
    	int A;
    	bool K;
    	char C;
    	C=A=K=0;
    	while(C<'0'||C>'9')K|=C=='-',C=getchar();
    	while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
    	return(K?-A:A);
    }
    void write(int X)
    {
    	if(X<0)putchar('-'),X=-X;
    	if(X>9)write(X/10);
    	putchar(X%10|48);
    }
    inline void add(int u,int v)
    {
    	e[++g].to=v;
    	e[g].next=head[u];
    	head[u]=g;
    }
    inline bool cmp1(int _,int __)
    {
    	return dfn[_]<dfn[__];
    }
    inline bool cmp2(int _,int __)
    {
    	return(dep[_]==dep[__]?_<__:dep[_]<dep[__]);
    }
    int lca(int x,int y)
    {
    	if(dep[x]<dep[y])swap(x,y);
    	while(dep[x]>dep[y])x=fa[x][bin[dep[x]-dep[y]]];
    	if(x==y)return x;
    	int i;
    	Down(i,bin[dep[x]],0)
    	if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    	return fa[y][0];
    }
    void dfs(int u)
    {
    	int i=0,v;
    	dep[u]=dep[fa[u][0]]+1;
    	dfn[u]=++cnt;
    	siz[u]=1;
    	while(1<<++i<=dep[u])fa[u][i]=fa[fa[u][i-1]][i-1];
    	for(i=head[u];i;i=e[i].next)
    	{
    		v=e[i].to;
    		if(v!=fa[u][0])
    		{
    			fa[v][0]=u;
    			dfs(v);
    			siz[u]+=siz[v];
    		}
    	}
    }
    inline int calc(int x,int y)
    {
    	return dep[x]+dep[y]-(dep[lca(x,y)]<<1);
    }
    int get(int u,int num)
    {
    	int i;
    	Down(i,bin[num],0)
    	if(num>=1<<i)u=fa[u][i],num-=1<<i;
    	return u;
    }
    int main()
    {
    	int n,i,x,y,t,m,j,k,pos,p,q;
    	n=read();
    	For(i,2,n)
    	{
    		x=read(),y=read();
    		add(x,y),add(y,x);
    	}
    	t=read();
    	dfs(1);
    	bin[0]=-1;
    	For(i,1,n)bin[i]=bin[i>>1]+1;
    	while(t--)
    	{
    		m=read();
    		For(i,1,m)h[i]=id[i]=read(),type[h[i]]=1;
    		sort(h+1,h+m+1,cmp1);
    		For(i,1,m-1)h[i+m]=lca(h[i],h[i+1]);
    		m+=m-1;
    		sort(h+1,h+m+1,cmp1);
    		m=unique(h+1,h+m+1)-h-1;
    		For(i,2,m)last[h[i]]=lca(h[i-1],h[i]);
    		sort(h+1,h+m+1,cmp2);
    		For(i,1,m)
    		if(type[h[i]])
    		{
    			j=h[i];
    			while(j&&!col[j])j=last[j];
    			if(!j)
    			{
    				j=h[i];
    				while(j&&!col[j])col[j]=h[i],j=last[j];
    				ans[h[i]]=n;
    				continue;
    			}
    			/*cout<<h[i]<<' '<<j<<"!!!
    ";*/
    			k=h[i];
    			while(1)
    			{
    				p=calc(col[j],last[k]),q=calc(h[i],last[k]);
    				/*cout<<col[j]<<' '<<h[i]<<' '<<k<<' '<<p<<' '<<q<<"???
    ";*/
    				if(p>q||p==q&&h[i]<col[j])k=last[k];
    				else break;
    			}
    			p=calc(col[j],k),q=calc(h[i],k);
    			pos=k;
    			/*cout<<col[j]<<' '<<h[i]<<' '<<k<<' '<<p<<' '<<q<<"!!!
    ";*/
    			k=get(k,((p+q-(col[j]<h[i]))>>1)-q);
    			ans[col[j]]-=siz[k];
    			ans[h[i]]=siz[k];
    			j=h[i];
    			while(j!=pos)
    			{
    				/*cout<<j<<' '<<h[i]<<"???
    ";*/
    				col[j]=h[i];
    				j=last[j];
    			}
    			col[j]=h[i];
    		}
    		For(i,1,m)
    		if(id[i])
    		{
    			write(ans[id[i]]);
    			putchar(' ');
    			id[i]=0;
    		}
    		else break;
    		For(i,1,m)type[h[i]]=ans[h[i]]=col[h[i]]=last[h[i]]=0;
    		putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用beautiful soup解析xml
    mongodb下载以及连接
    beautiful soup解析有空格的class
    爬取糗事百科的热门段子,以及热图链接
    结果记录
    安装自然语言处理工具Nltk以及初次使用
    AD文献分析 整体框架和数据设计
    遍历目录,目录下文件名存入文件
    dict,列表方法
    工具集
  • 原文地址:https://www.cnblogs.com/May-2nd/p/14269632.html
Copyright © 2011-2022 走看看