zoukankan      html  css  js  c++  java
  • $Luogu$ $P1196$ $[NOI2002]$ 银河英雄传说

    链接

    背景

    (CCF) (NOI) (2002) (T1)(Luogu) (P1196/Vijos1443)

    题意

    给出 (30000) 艘战舰排成一行(从 (1)(30000) 编号),每艘独占一列。给出 (T) 条指令,形如 (M x y)(C x y) ,前一个表示第 (x) 号战舰所在的一列战舰整体平移到第 (y) 号战舰所在的一列战舰的后方,后一个表示查询第 (x) 号战舰和第 (y) 号战舰是否在同一列,若是的话还要查询两艘战舰之间隔着几艘战舰。

    解法

    考虑把每个战舰当做一个集合,用并查集维护当前战舰所在的集合的首个元素。当然,仅仅这样是不够的。由于要查询两艘战舰之间隔着几艘战舰,考虑维护每艘战舰 (x) 到首个元素(列首)的距离 (d_x) 。对于一个 (M) 操作,相当于是把 (x) 的代表元素作为 (y) 所在集合的一个节点,于是向 (y) 的代表元素合并 (x) 的代表元素即可。
    考虑合并的过程怎么更新 (d_x) 。求 (d_x) 的过程就是把它到根节点之间的所有边权求个和。于是魔改一下查询代表元素的函数即可。合并完之后考虑 (d_x) 已经被更新了,新的值是 (y) 所在集合的总战舰数,于是还要记一个 (siz_x) 表示节点 (x) 所在集合的元素数。也要动态维护。
    然后是 (C) 操作。显然直接查询 (x) 的代表元素和 (y) 的代表元素是否相同即可判定是否在同一列。然后两艘战舰之间隔着的战舰数就是 (left| d_x-d_y ight| -1) ,即两点到代表元素的距离之差减去一个元素的值。

    (trick)

    为每个节点 (i) 安排一个权值 (d_i) 用来回答询问或者判定合法性。注意 (d) 数组的维护方法(先递归找代表再累加权值)。

    代码

    $View$ $Code$
    
    //省略头文件
    using namespace std;
    inline int read()
    {
    	int ret=0,f=1;
    	char ch=getchar();
    	while(ch>'9'||ch<'0')
    	{
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		ret=(ret<<1)+(ret<<3)+ch-'0';
    		ch=getchar();
    	}
    	return ret*f;
    }
    int T,x,y,fa[30005],d[30005],siz[30005];
    char op;
    int get(int x)
    {
    	if(x==fa[x])
    		return x;
    	int rt=get(fa[x]);
    	d[x]+=d[fa[x]];
    	return fa[x]=rt;
    }
    int main()
    {
    	T=read();
    	for(register int i=1;i<=30000;i++)
    	{
    		fa[i]=i;
    		siz[i]=1;
    	}
    	while(T--)
    	{
    		scanf("%c",&op);
    		x=read();
    		y=read();
    		if(op=='C')
    		{
    			int fx=get(x),fy=get(y);
    			if(fx!=fy)
    				printf("-1
    ");
    			else
    				printf("%d
    ",abs(d[x]-d[y])-1);
    		}
    		else
    		{
    			int fx=get(x),fy=get(y);
    			fa[fx]=fy;
    			d[fx]=siz[fy];
    			siz[fy]+=siz[fx];
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    宿主机无法访问CentOS7上Jenkins服务的解决办法
    415. Add Strings
    367. Valid Perfect Square
    326. Power of Three
    258. Add Digits
    231. Power of Two
    204. Count Primes
    202. Happy Number
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/Peter0701/p/11808785.html
Copyright © 2011-2022 走看看