私は一人で出てくると、まだ非常に満足してカットオフしたい〜
コード:
#include <ビット/ STDC ++。H> に#define N 400005 の#define INF 1000000000 freopenはfreopenはの#define setIO(S)(S ".IN"、 "R"、STDIN)、(S ".out"を、 "W"、 STDOUT) 名前空間stdを使用。 INT RT [N]。 構造体のエッジ { U、V、C int型。 エッジ(INT U = 0、INT V = 0、INT C = 0):U(U)、V(V)、C(C){} } E [N]。 構造体Union_Find_set { int型のP [N]。 INITを無効() { [I] = iがP(++ iは; iがNを<I = 0をINT)ため、 } INT(INT X)を見つける { ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。 } int型のマージ(int型のx、int型のY) { X =検索(X)、Y =(y)を見つけます。 IF(!X = Y) { !返す(T [T [X] .F] .CH [0] == X || T [T [X] .F] .CH [1] == X) } P [X] = Y。 1を返します。 } 他 { 0を返します。 } } } UFS。 構造体Link_Cut_Tree { の#define LSONのT [X] .CH [0] の#define rson T [X] .CH [1] INT STA [N]。 構造体ノード { INT CH [2]、F、分、ID、ヴァル、REV。 } T [N]。 INT GET(INT X) { [1] == X [T [X] .F] .CH Tを返します。 } INT ISRT(INT X) ボイド押し上げ(INT X) { T [X] .min = T [X] .val、T [X] = xを.ID。 もし(Tの【のLSON] && LSON .min <T [X] .min)T [X] .min = T [LSON] .min、T [X] .ID = T [LSON] .ID。 IF(rson && T [rson] .min <T [X] .min)T [X] .min = T [rson] .min、T [X] .ID = T [rson] .ID。 } ボイドマーク(INT X) { IF(x)はT [X] .rev ^ = 1、スワップ(LSON、rson)。 } ボイドプッシュダウン(int型X) { IF(X && T [X] .rev) { T [X] .rev = 0。 (LSON)マーク(LSON)であれば、 もし(rson)マーク(rson)。 } } ボイド回転(int型X) { INT古い= tの[X] .F、=さt(x)を取得= [古い] .Fを折ります。 (!ISRT(旧))であればT [倍] .CH = xの[T [1] ==古い[] .CH倍]。 T [古い] .CH [た] = tの[X] .CH [れる^ 1]、T [T [古い] .CH [れる] F =古いです。 T [X] .CH古い= [れる^ 1]、T = xと.F [古い]、T [X] .F =折ります。 腕立て伏せ(旧)、腕立て伏せ(x)は、 } ボイドスプレイ(INT X) { int型のV = 0、U = Xを、FA。 STAは[++ V] T [U] .Fを=(!; ISRT(u)はuが= T [U] .F STA [++ V = U)のために 用(; V; - v)の押下(STA [V])。 (U = T [U] .F(FA = tの[X] .F)= Uが;!(X)を回転させる)ための 場合(T [FA] .F = uは!) (==)(FAを取得回転?(x)のFAを取得します。x); } ボイドアクセス(int型X) { (; X; Y = X、X = T [X] .F INT Y = 0)のための スプレイ(X)、rson = Y、押し上げ(X)。 { } 無効makeroot(int型x)の INTの更新(int型のx、int型のL、R INT、INT P、INT D) アクセス(X)、スプレイ(X)、マーク(X)。 } ボイドスプリット(int型のx、int型のY) { makeroot(X)、アクセス(Y)、スプレイ(Y)。 } ボイドリンク(int型のx、int型のY) { makeroot(x)は、T [X] .F = Y。 } ボイドカット(int型のx、int型のY) { makeroot(X)、アクセス(Y)、スプレイ(Y)。 T [Y] .CH [0] = tの[X] .F = 0。 突き上げ(Y)。 } の#undef LSON用 の#undef rson } LCT。 構造体Segment_Tree { int型のTOT。 INTのLSON [N * 20]、rson [Nの* 20]、合計[N * 20]。 { INT OO = ++ TOT。 LSON [OO] = LSON [X]、rson [OO] =のrson [X]、和[OO] =和[X] + D。 IF(L == R)戻りOO。 INT半ば=(L + R)>> 1。 IF(p <= MID)LSONの【のOO] =アップデート(LSON [x]は、L、中、P、D)。 他rson [OO] =アップデート(rson [x]は、中間+ 1、R、P、D)。 OOを返します。 } INTクエリ(int型のx、int型のL、int型のR、int型のL、R INT) { (!X)であれば0を返します。 IF(L> = L && R <= R)戻り和[X]。 半ば=(L + R)>> 1、INT、再= 0。 IF(L <= MID)再+ =クエリ(LSON [x]は、L、中、L、R)。 IF(R> MID)再+ =クエリ(rson [x]は、中間+ 1、R、L、R)。 再を返します。 } } TR。 int型のmain() { // setIO(」 int型N、M、I、J、K、TY。 scanf関数( "%D%D%D%D"、&N、&M、&K、&TY)。 lct.t [0] .val = INF。 lct.t [I] .val = INF、lct.pushup(I)、(I ++; iが<= N I = 1)のために ufs.init(); (; I <= M + I I = 1)のための { scanf関数( "%D%D"、&E [I] .U、&E [I] .V)。 int型のu = E [i]の.U。 int型のV = E [i]の.V。 int型_new =私はN +; RT [I] =のRT [I-1]; (U == V)であれば { 続けます。 } RT [I] = tr.update(RT [I-1]、1、M、I、1)。 IF(ufs.merge(U、V)) { lct.t [_new] .val = I。 lct.pushup(_new)。 lct.link(U、_new)。 lct.link(_new、V); } 他 { lct.split(U、V)。 INT CC = lct.t [V] .ID。 lct.cut(CC、E [CC-N] .U)。 lct.cut(CC、E [CC-N] .V)。 RT [I] = tr.update(RT [I]、1、M、CC-N、-1); lct.t [_new] .val = I。 lct.pushup(_new)。 lct.link(_new、U)。 lct.link(_new、V); } } int型lastans = 0。 用(i = 1; iは= K <; ++ I) { int型のL、R。 scanf関数( "%dの%のD"、&L&R)。 (TY)の場合 { L ^ = lastans。 R ^ = lastans。 IF(L> R)スワップ(L、R)。 } lastans = N-tr.query(RT [R]、1、M、L、R)。 printf( "%d個の\ n"、lastans)。 } 0を返します。 }