題目提供者該使用者不存在
標籤並查集noi系列2001(或之前)
難度提高+/省選-
提交該題 討論 題解 記錄
公元五八○一年,地球居民遷移至金牛座α第二行星,在那裡發表銀河聯邦
創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。
宇宙歷七九九年,銀河系的兩大軍事集*在巴公尺利恩星域爆發戰爭。泰山壓
頂集**宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集*點名將楊
威利組織麾下三萬艘戰艦迎敵。
楊威利擅長排兵布陣,巧妙運用各種戰術屢次以少勝多,難免恣生驕氣。在
這次決戰中,他將巴公尺利恩星域戰場劃分成30000列,每列依次編號為1, 2, …,
30000。之後,他把自己的戰艦也依次編號為1, 2, …, 30000,讓第i號戰艦處於
第i列(i = 1, 2, …, 30000),形成「一字長蛇陣」,誘敵深入。這是初始陣形。當
進犯之敵到達時,楊威利會多次發布合併指令,將大部分戰艦集中在某幾列上,
實施密集攻擊。合併指令為m i j,含義為讓第i號戰艦所在的整個戰艦佇列,作
為乙個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部。顯然戰艦
佇列是由處於同一列的乙個或多個戰艦組成的。合併指令的執行結果會使佇列增
大。 然而,老謀深算的萊因哈特早已在戰略上取得了主動。在交戰中,他可以通
過龐大的情報網路隨時監聽楊威利的艦隊調動指令。
在楊威利發布指令調動艦隊的同時,萊因哈特為了及時了解當前楊威利的戰
艦分布情況,也會發出一些詢問指令:c i j。該指令意思是,詢問電腦,楊威利
的第i號戰艦與第j號戰艦當前是否在同一列中,如果在同一列中,那麼它們之
間布置有多少戰艦。
作為乙個資深的高階程式設計員,你被要求編寫程式分析楊威利的指令,以
及回答萊因哈特的詢問。
最終的決戰已經展開,銀河的歷史又翻過了一頁……
輸入格式:
輸入檔案galaxy.in的第一行有乙個整數t(1<=t<=500,000),表示總共有t
條指令。
以下有t行,每行有一條指令。指令有兩種格式:
m i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。
該指令是萊因哈特竊聽到的楊威利發布的艦隊調動指令,並且保證第i號戰
艦與第j號戰艦不在同一列。
c i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。
該指令是萊因哈特發布的詢問指令。
輸出格式:
輸出檔案為galaxy.out。你的程式應當依次對輸入的每一條指令進行分析和
處理:如果是楊威利發布的艦隊調動指令,則表示艦隊排列發生了變化,你的程式
要注意到這一點,但是不要輸出任何資訊;
如果是萊因哈特發布的詢問指令,你的程式要輸出一行,僅包含乙個整數,
表示在同一列上,第i 號戰艦與第j 號戰艦之間布置的戰艦數目。如果第i 號戰
艦與第j號戰艦當前不在同一列上,則輸出-1。
輸入樣例#1:
4輸出樣例#1:m 2 3
c 1 2
m 2 4
c 4 2
-1【樣例說明】1
戰艦位置圖:**中阿拉伯數字表示戰艦編號
分析:做這道題有點鬼畜啊,在洛谷上ac,在codevs上wa,改了一下發現在洛谷wa,codevsac,然後改了一下發現又全wa,我以為網路問題,再提交了一遍,發現洛谷ac了,好吧,我也不知道該怎麼辦了......
其實這道題可以把每一列抽象成乙個集合,然後發現有合併操作,很明顯就是並查集,但是還要查詢個數,怎麼辦呢?直接求似乎很難,那麼轉換一下?可以聯想到在樹中求一條邊的長度,即點i到根的距離-點j到根的距離的絕對值,so,這道題也可以利用這種思想,但是到根的距離怎麼算呢?
其實根就是每一列的第乙個,因為每兩艘戰艦的距離為1,所以到根的距離可以當做到根的戰艦的個數,如果查詢x,y,設d[i]為i到根節點的距離,那麼答案就是abs(d[x] - d[y]) - 1,但是d陣列怎麼算呢?如果把x的父節點設定為y(合併),那麼這個時候d[x] = num[y](將x所在列插入到y後面,那麼x自然就在y列的末尾),num[y] += num[x],這個時候num[x] = 0(不存在了).
find函式也需要改改,因為num陣列在合併的時候處理了,只需要在find函式中累加即可,那麼fa陣列該怎麼處理呢?這個時候在函式中傳遞乙個引用引數即可.
#include #include#include
#include
#include
#include
using
namespace
std;
const
int maxn = 30000
;int
t, fa[maxn], d[maxn], num[maxn];
int find(int x,int &tempfa) //
更改fa陣列
else
}void hebing(int x,int
y)void xunwen(int x,int
y)int
main()
while (t--)
return0;
}
NOI2002 銀河英雄傳說
noi2002 day1 t1 公元5801年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集團在巴公尺利恩星域爆發戰爭。泰山壓頂集團派宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集團點名將楊威利組織...
NOI 2002 銀河英雄傳說
有 n 列戰場,每一列一開始只有乙個戰艦,編號就是對應的戰場編號。有 m 次操作 注意每一列戰場的戰艦都是排成一列的。帶偏移量的並查集。記錄 d x 表示 x 到所在列頭的一段上共有多少個戰艦。記錄 sz x 表示 x 所在的一列有多少個戰艦。為了保證複雜度,我們在做的時候還是要路徑壓縮。但是 d ...
NOI2002 銀河英雄傳說
公元五八 一年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭。泰山壓頂集 宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集 點名將楊威利組織麾下三萬艘戰艦迎敵。楊威利擅長排兵...