チップ:
10≤N 4入力がない場合、パスが出て圧縮することができる続きます。
10000
2 1 2
2 3 4
2 5 6
......
2 9997 9998
2 9999万
2 9999 9997
......
2 5 3
2 3 1
10000
10000 10000
......
10000 10000
しかし、実際には約50ミリ秒の運転時間の2つの用法。
$ {O _ {\左(N ^ 2/2 \右)}} $:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 M = 11000 ; int型の金[M]; BOOL VIS [M]; INT(検索のint {X)の 一方(!X =金[X])はx = 金[X]。 戻り値は、X; } ボイド連合(int型 A、INT B){ int型 FRIA = 探す(A)。 int型 friB = (B)検索; もし(FRIA> friB)金[FRIA] = friB。 もし(friB> FRIA)金[friB] = FRIA。 } int型メイン()は、 { ため(INT iが= 0 ; I <M、I ++)金[I] = iが、 int型のn; cinを>> N; 以下のために(INT iが= 0 ; N iが<; I ++ ){ int型の K; CIN >> K。 int型[k]を、 用(INT J = 0 ; J <K、J ++ ){ CIN >> [J]。 VIS [[J] = 真; もし(J)ユニオン([J]、[J- 1 ])。 } } int型人々 = 0、部族= 0 ; 以下のために(INT iが= 0 ; I <Mを、I ++ ){ 場合(VIS [i])と++ 人。 もし(VIS [I] &&金[I] == I)++ 部族。 } coutの <<人々 << " " <<部族<< " \ n個" ; int型 Q; cinを>> Q; 用(INT iは= 0 ; I <Q I ++ ){ int型 A、B、CIN >> B。 coutの <<((B)を検索==(a)の検索?」:" N ")<< " \ n個" ; } 戻り 0 。 }
$ {O _ {\左(N \右)}} $:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 M = 11000 ; int型の金[M]; BOOL VIS [M]; INT検索(INT X){ int型 F = X。 しばらく = F(!F =金[F])金[F]。 INT A = X、B。 一方、(!=金[])B =金[A]、金[A] = F、= B。 リターンF; } ボイド連合(int型 A、INT B){ int型 FRIA = 探す(A)。 int型 friB =(B)の検索; もし(FRIA> friB)金[FRIA] = friB。 もし(friB> FRIA)金[friB] = FRIA。 } int型のmain() { ために(INTは iは= 0 ; I <M、I ++)金[I] = I。 int型のn; cinを>> N; 以下のために(INT iが= 0 ; N iが<; I ++ ){ int型の K; CIN >> K。 int型[k]を、 用(INT J = 0 ; J <K、J ++ ){ CIN >> [J]。 VIS [[J]]= 真; もし(J)ユニオン([J]、[J- 1 ])。 } } int型の人= 0、部族= 0 ; 以下のために(INT iが= 0 ; I <Mを、I ++ ){ 場合(VIS [i])と++ 人。 もし(VIS [I] &&金[I] == I)++ 部族。 } coutの <<人々 << " " <<部族<< " \ n個" ; int型 Q; cinを>> Q; 以下のための(int型 I = 0; I <Q、I ++ ){ int型、B; CIN >> B。 coutの <<(()==(B)を探す?" Y ":" N ")<< " \ nは" ; } 戻り 0 。 }