並查集 銀河英雄傳說

2021-08-03 20:13:36 字數 2797 閱讀 1427

description

公元五八○一年,地球居民遷移至金牛座α第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。

宇宙歷七九九年,銀河系的兩大軍事集團在巴公尺利恩星域爆發戰爭。泰山壓頂集團派宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集團點名將楊威利組織麾下三萬艘戰艦迎敵。

楊威利擅長排兵布陣,巧妙運用各種戰術屢次以少勝多,難免恣生驕氣。在這次決戰中,他將巴公尺利恩星域戰場劃分成30000列,每列依次編號為1, 2, …, 30000。之後,他把自己的戰艦也依次編號為1, 2, …, 30000,讓第i號戰艦處於第i列(i = 1, 2, …, 30000),形成「一字長蛇陣」,誘敵深入。這是初始陣形。當進犯之敵到達時,楊威利會多次發布合併指令,將大部分戰艦集中在某幾列上,實施密集攻擊。合併指令為m i j,含義為讓第i號戰艦所在的整個戰艦佇列,作為乙個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部。顯然戰艦佇列是由處於同一列的乙個或多個戰艦組成的。合併指令的執行結果會使佇列增大。

然而,老謀深算的萊因哈特早已在戰略上取得了主動。在交戰中,他可以通過龐大的情報網路隨時監聽楊威利的艦隊調動指令。

在楊威利發布指令調動艦隊的同時,萊因哈特為了及時了解當前楊威利的戰艦分布情況,也會發出一些詢問指令:c i j。該指令意思是,

詢問電腦,楊威利的第i號戰艦與第j號戰艦當前是否在同一列中,如果在同一列中,那麼它們之間布置有多少戰艦。

作為乙個資深的高階程式設計員,你被要求編寫程式分析楊威利的指令,以及回答萊因哈特的詢問。

最終的決戰已經展開,銀河的歷史又翻過了一頁……

input

輸入檔案的第一行有乙個整數t(1<=t<=500,000),表示總共有t條指令。

以下有t行,每行有一條指令。指令有兩種格式:

1. m i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。該指令是萊因哈特竊聽到的楊威利發布的艦隊調動指令,並且保證第i號戰艦與第j號戰艦不在同一列。

2. c i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。該指令是萊因哈特發布的詢問指令。

output

你的程式應當依次對輸入的每一條指令進行分析和處理:

如果是楊威利發布的艦隊調動指令,則表示艦隊排列發生了變化,你的程式要注意到這一點,但是不要輸出任何資訊;

如果是萊因哈特發布的詢問指令,你的程式要輸出一行,僅包含乙個整數,表示在同一列上,第i號戰艦與第j號戰艦之間布置的戰艦數目。如果第i號戰艦與第j號戰艦當前不在同一列上,則輸出-1。

sample input

4

m 2 3

c 1 2

m 2 4

c 4 2

sample output

-1

1

data constraint

hint

題解

題目就是說,一開始30000個點是散開的,隨後進行若干次合併,既把乙個點所在的序列並到另一條序列後面。

我們可以用並查集,再用乙個字首和,表示它所在的序列在它之後有幾個點。找根節點回溯回來時,順便更新

字首和。

var

t,i,x,y:longint;

n:char;

f,b,c:array[0..30000]of longint;

function get(a:longint):longint;

begin

if f[a]=a then exit(a);

get:=get(f[a]);

b[a]:=b[a]+b[f[a]]-1;

f[a]:=get;

exit(get);

end;

procedure hb(x,y:longint);

var i,j:longint;

begin

i:=get(x);

j:=get(y);

if i<>j then

begin

f[i]:=j;

b[i]:=b[i]+c[j];

c[j]:=c[j]+c[i];

end;

end;

procedure ans(x,y:longint);

begin

if get(x)<>get(y) then writeln(-1)

else writeln(abs(b[x]-b[y])-1);

end;

begin

assign(input,'galaxy.in');reset(input);

assign(output,'galaxy.out');rewrite(output);

readln(t);

for i:=1 to 30000 do

begin

f[i]:=i;

b[i]:=1;

c[i]:=1;

end;

for i:=1 to t do

begin

readln(n,x,y);

if n='m' then hb(x,y)

else ans(x,y);

end;

close(input);close(output);

end.

並查集 銀河英雄傳說

2002年noi全國競賽 時間限制 1 s 空間限制 256000 kb 題目等級 大師 master 公元五八 一年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭。泰山壓頂集 ...

銀河英雄傳說(並查集操作)

p1196 noi2002 銀河英雄傳說 鏈結戳這裡 銀河英雄傳說 先不說什麼,直接上 吧!include include include include using namespace std struct sdnode 300003 int njc int n int father int v ...

方塊遊戲 (銀河英雄傳說)(並查集)

方塊遊戲 cubes.pas c cpp 題目描述 小a和小b在玩乙個方塊遊戲。編號為1到n 1 n 30000 的n個方塊正放在地上。每個構成乙個立方柱。遊戲開始後,小a會給小b發出p 1 p 100000 個指令。1 移動 m 將包含x的立方柱移動到包含y的立方柱上。2 統計 c 統計含x的立方...