並查集解析 問題 銀河英雄傳說

2021-10-05 17:01:03 字數 2801 閱讀 8922

題目描述

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

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

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

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

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

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

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

輸入輸入的第一行有乙個整數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),表示指令涉及的戰艦編號。該指令是萊因哈特發布的詢問指令。

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

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

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

樣例輸入

4m 2 3

c 1 2

m 2 4

c 4 2

樣例輸出-11

參考了很多文章但是還是弄不明白 最終在乙個個資料帶入中對**有了想法.

解題思路: back[i]=i 所有後面的包括自己;pre 不包括自己

合併之後是無法解體的,只能尾巴接頭部.所以想要得出兩架飛機之間的個數,在每次合併飛機的時候,算一下在這飛機之後有多少個飛機,在這飛機之前有多少個飛機,合併的時候 比如2->1 4->3 將4連到2後面, 即 將3接到1下面

fx=1 fy=3 ;

f[3]=1 pre[3]=back[1]=2 解讀為 3接在1後面 所以3的前面全是1的元素 back[1]=back[1]+back[3] 解讀為1後面接上3的元素

但是f』[3]=1覺得不妥

我們現在追加乙個 5->4 加到1下面 f[5]=1 pre[5]=back[1] 此時的back[1]已經追加了3和4了 是成立的

最終檢查兩架飛機的時候例如3 和5 都會找到飛機1;

abs(pre[x]-pre[y])-1 最終用飛機3之前的所以飛機-飛機5之前所有的飛機-飛機5 就得到答案

解釋一下find裡面的 pre[x]=pre[x]+pre[f[x]]; 將該個節點之前的飛機全部加上

還是上面的例子 連線1和2 之後 查詢 2的時候 pre[2]+=pre[1] 連線3和4之後查詢 4 pre[4]+=pre[3];

連線4和2 即連線3->1之後 查詢 2到4的之間

pre[4] =pre[4]+pre[3]+pre[1] pre[1]= 0 pre[3]的時候接了1和2的飛機=2

pre[2]=pre[2]+pre[1]=1

2-1-1=0

我感覺一般人很難想到怎麼寫,大概只有那種天才才能一下子畫出圖得到想法吧.

記得畫圖理解

溫習提示 用c++的cin後cout會超時即使用了ios::sync_with_stdio(false);

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxn=

500001

;int n;

int f[maxn]

,pre[maxn]

,back[maxn]

;struct node

b[maxn]

;int

find

(int x)

void

unit

(int x,

int y)

bool

jude

(int x,

int y)

intmain()

for(

int i=

1;i<=n;i++)if

(st==

'c')

}return0;

}

並查集 銀河英雄傳說

description 公元五八 一年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集團在巴公尺利恩星域爆發戰爭。泰山壓頂集團派宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集團點名將楊威利組織麾下三萬...

並查集 銀河英雄傳說

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

銀河英雄傳說

公元五八 一年,地球居民遷至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭。泰山壓頂集 宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集 點名將楊威利組織麾下三萬艘戰艦迎敵。楊威利擅長排兵布...