洛谷 1196 NOI2002 銀河英雄傳說

2021-09-24 15:08:53 字數 1786 閱讀 9798

題目描述

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

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

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

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

在楊威利發布指令調動艦隊的同時,萊因哈特為了及時了解當前楊威利的戰艦分布情況,也會發出一些詢問指令:ci,j​。該指令意思是,詢問電腦,楊威利的第iii號戰艦與第jjj號戰艦當前是否在同一列中,如果在同一列中,那麼它們之間布置有多少戰艦。

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

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

輸入輸出格式

輸入格式:

第一行有乙個整數t(1≤t≤500,000),表示總共有t條指令。

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

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

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

輸出格式:

依次對輸入的每一條指令進行分析和處理:

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

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

輸入輸出樣例

輸入樣例#1:

4m 2 3

c 1 2

m 2 4

c 4 2

輸出樣例#1:-11

解釋:帶權並查集,dis[i]是i到祖先的路徑上的個數,num[i]是以i為根的話,其集合中有多少個。然後維護就好了,這裡有個問題沒考慮到,在find裡面維護的時候直接拿父親節點的dis加1取跟新節點,這樣是錯的,沒考慮周全。

#include#include#include#include#define n 40000

using namespace std;

int father[n]=;

int dis[n]=;

int num[n]=;

void init()

int t=0;

int main()

}return 0;

}

洛谷 P1196 NOI2002 銀河英雄傳說

有30000列,每列都有一艘戰艦,編號1 30000 有2種操作 1.將一列的戰艦運到另一列 2.詢問兩個戰艦是否在同一列,如果是,求出它們之間的距離 並查集,維護每個點x離自己祖先的距離dis x 和該點所在集合的大小size x 每次查詢時更新即可,點x,y之間距離為abs dis x dis ...

P1196 NOI2002 銀河英雄傳說

題目 p1196 noi2002 銀河英雄傳說 分析 對於m指令,一次移動整列,並且是把兩列合併成一列。對於c指令 判斷飛船 i 和飛船 j 是否在同一列,若在,則輸出它們中間隔了多少艘飛船。由於需要判斷是否在同一列,每列初始都只有一艘飛船,之後需要不斷合併,所以很容易就想到要用並查集來實現。ac ...

p1196 NOI2002 銀河英雄傳說

所謂帶權並查集 本題所求的不止是兩個編號之間是否有關係,還要求兩個編號之間有什麼關係,這就要求我們維護多個陣列,fa陣列維護兩個編號之間的連通性,re維護編號為i的戰艦到fa i 之間的距離,num維護編號為i的戰艦所在的那一列有多少戰艦。include include include includ...