そこ引き戻し操作は、オフラインで検討しているので、あなたは、操作の最終シーケンスを知っています
操作は、それはもはや汚れている場合は、以前に染めていない位置から直接操作するだけで、前方、背面カバーの前面に記載されています
だから我々は位置上で動作する、$ N $ N $行$リンクリストを維持することができ、リストから直接削除することができます
複雑さは、ほぼ、次いで$コードが$ n番目の互いに素な集合ラインを維持することである$(NM)O $、です
#include <iostreamの> する#include <cstdioを> する#include <アルゴリズム> の#include <CStringの> する#include <cmath> 使用して 名前空間STD。 typedefの長い 長いLL。 インラインint型リード() { int型のx = 0、F = 1。チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1。CH =getchar関数(); } 一方、(CH> = ' 0 ' && CH <= ' 9 '){X =(X << 1)+(X << 3)+(CH ^ 48)。CH = GETCHAR()。} 戻りのx *のF。 } のconst int型 N = 1007、M = 1E5 + 7 。 INTの N、M、D [M] [ 5 ] から[M]、SAV [M]、TOT。 INTのMP [N] [N]。 構造体DSU { INT FA [N]。 無効のinit(){ 用(INT I = 0を; iが<= N + 2、iが++)FAを[I] = I。} インラインint型の検索(int型 X){ 戻り X == FA [X]?X:FA [X] = 見つける(FA [X])。} } G [N]。 INT ()は、メイン { N =(読み取り)、M =(読み取り)、M = (読み取り) 以下のために(int型 i = 0 ; iがn <I ++はグラム[I] .INIT())。 int型になりました= 0 ; チャー S [ 7 ]。 以下のために(int型 I = 1 ; I <= M; iは++ ) { scanf関数(" %sの"、S + 1 )。 もし(S [ 1 ] == ' P ' ) { ためには、(int型 J = 0 ; J < 5 ; J ++)D [i]は[J] = 読み取ります(); 今[I] =。今= I; } そうであれば(S [ 1 ] == ' S ')SAV [++ TOT = 今。 他の今= SAV [読み取り()]; } のために(int型 i = 0 ; iがn <; iは++ ) のために(INT J = 0 ; J <N; J ++)MP [I] [J] = 1 。 int型XA、YA、XB、YB、C。 一方、(今) { C = D [今] [ 0 ]、XA = D [今] [ 1 ]、屋= D [今] [ 2 ]、XB = D [今] [ 3 ]、YB = D [今] [ 4 ]。 以下のために(int型 iは第Xa =; I <= XB、I + = 2 ) のために(INT J = G [i]は.find(YA); J <= YB、J = G [i]が.find(J + 2 )) G [I]の.Fa [J] = G [i]は.find(J + 2)、MP [I] [J] =のCと、 以下のための(int型I = XA + 1 ; I <= XB、I + = 2 ) のための(INT J = G [i]は.find(YA + 1); J <= YB、J = G [i]が.find(J + 2 )) G [ I]の.Fa [J] = G [i]は.find(J + 2)、MP [I] [J] =のC。 今 = から[今]。 } のために(int型 I = 0 ; iがN <; I ++は、プット("" )) のために(INT J = 0 ; J <N; J ++)のprintf(" %dの" 、MP [I] [J])。 リターン 0 ; }