合併の複雑さに関係するヒューリスティックがnlongされます
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define担当者(I、B)(I =(A)がINT;方には<=(B); iが++) の#define repp(I、B)(I =(A)がINTのために、I> = (B); - I) の#defineは長い長いっ の#defineは(X)(CERR <<(#X)<< '=' <<(X)<< ENDL)を参照 の#define INF 0x3f3f3f3f の#define CLR( 、V)のmemset(A、V、はsizeof A) ///////////////////////////////// / CONST INT N = 2E6 + 10 。 int型のヘッド[N]、SIZ [N]、POS、C [N]、[N]、ST [N]、F ANS、N、M。 INTのNEX [N]。 構造体のエッジ{ INT NEX、へ;}エッジ[N << 1 ]。 (追加INT A、INT B){;ヘッド[A] =エッジ[++ POS] =(エッジ){B、ヘッド[A]} ; POS} int型のマージ(int型のx、int型のY) { ため(int型私は=ヘッド[X]; I; I = エッジ[i]は.nex) { int型 V = エッジ[I] .TO。 ANS - =(Y == C [V- 1 ])+(Y == C [v + 1 ])。 } のための(INTは I =ヘッド[X]; I; I =エッジ[i]は.nex)C [エッジ[i]は.TO] = Y。 エッジ[ST [X]] NEX。 =頭部[Y];頭部[Y] =頭部[X]; SIZ [Y] + = SIZ [X]。 ヘッド[X] = SIZ [X] = ST [X] = 0 ; } int型のmain() { scanf関数(" %D%dの"、&N、&M)。 担当者(I、1 、N) { scanf関数(" %のD "、&C [I]); F [C [I] =のC [i]は、 ANS!+ = C [I] = C [I- 1 ]; もし(!ヘッド[C [I]])ST [C [I] = POS + 1 ; SIZ [i]がC] ++ ;(、IをC [I])を加えます。 } 一方(M-- ) { int型の OP; scanf関数(" %のD "、&OP)。 もし(オペ== 2)のprintf(" %d個の\ n " 、ANS)。 他 { INTは X、Y; scanf関数(" %dの%のD "、およびX&Y)。 もし(x == y)を続けます。 もし(SIZ [F [X]]> ([X]、F [y]のF)SIZ [F [Y])スワップ。 もし(!SIZ [F [X]]) 続けます。 マージ(F [X]、F [Y])。 } } }