ICPCアジア南京2019のための予備コンテスト
至高の目標
#include <ビット/ STDC ++ H> 名前空間STDを使用して、 const int型MAXN = 10000; N INT、M。 構造体Spfa { 構造体のエッジは{ Wに、次のint型。 } E [MAXN]。 INTヘッド[MAXN]、V [MAXN]、D [MAXN]、TOL。 無効アドオン(int型のu、int型のV、int型のワット){ TOL ++; E [TOL] .TO = V。 E [TOL] .next =頭部[U]。 E [TOL] .W = W。 ヘッド[U] = TOL。 } キュー<整数> Q。 INT spfa(INT S、T INT){ memsetの(D、0x3fを、はsizeof(d)参照)。 memset(V、0、はsizeof(V))。 D [S] = 0; V [S] = 1。 q.push(S); しばらく(!q.empty()){ INT X = q.front()。 q.pop(); V [X] = 0; {(; I I = E [i]は.next I =ヘッド[X] INT)のための (D [E [i]は.TO]> D [X] + E [i]は.W){もし D [E [I] .TO] = D [X] + E [I] .W。 IF(V [E [i]は.TO] == 0){ V [E [i]は.TO] = 1。 q.push(E [I] .TO)。 } } } } 戻りD [T] == 0x3fを?-1:D [T]。 } ボイドのinit(){ memsetの(頭、0、はsizeof(ヘッド))。 TOL = 0; } } S。 メインINT(){ int型_。 scanf関数( "%のD"、&_)。 一方、(_--){ S.init()。 scanf関数( "%d個の%のD"、&N、&M)。 {(; iは<= M I ++はint型I = 1、U、V、W)のため のscanf( "%D%D%D"、&U&V、およびW) S.add(U、V、W)。 } (i = 1 INT、U、V;私は= 6 <; Iは++){ため のscanf( "%D%dの"、&U、およびV)。 INT ANS = S.spfa(V、U)。 printf( "%d個の\ n"、 - ANS)。 S.add(U、V、-ans)。 } } }
貪欲シーケンス
#include <ビット/ STDC ++ H> 名前空間STDを使用して、 const int型MAXN = 1E5 + 10。 INTのTOT、T [MAXN * 30]、ANS [MAXN]、L [MAXN * 30]、R [MAXN * 30]、[MAXN]、B [MAXN]、N、C [MAXN]、K。 ベクトル<整数>ルート。 INTビルド(int型のL、R INT){ int型ID = ++ TOT。 T [ID] = 0; IF(L == R)戻りID。 INT半ば=(L + R)>> 1。 L [ID] =(L、中間)を構築します。 R [ID] =ビルド(MID + 1、R)。 IDを返します。 } ボイドinsert1(INT ID1、INT X){ int型ID2 = ++ TOT。 root.push_back(ID2)。 T [ID2] = tの[ID1] + 1。 INT 1 = 1、R = N。 (L <R){ながら 1 INT半ば=(L + R)>>。 IF(X <= MID){ R =半ば; L [ID2] = ++ TOT。 R [ID2] = R [ID1]。 ID2 = TOT; ID1 = L [ID1]。 }他{ L =ミッド+ 1。 R [ID2] = ++ TOT。 L [ID2] = L [ID1]。 ID2 = TOT; ID1 = R [ID1]。 } T [ID2] = T [ID1] + 1。 } } int型Query1を(INT ID、int型のL、R INT、INT X){ 戻りT [ID](X> [R]を=)場合。 他の場合(X <[L])戻り0; int型のres = 0; INT半ば=(L + R)>> 1。 IF(X <= [中間])RES = Query1を(L [ID]、L、中、X)。 他{ RES + = T [L [ID]。 RES + = Query1を(R [ID]、ミッド+ 1、R、X)。 } RESを返します。 } INTクエリ(int型のL、R INT、INT LL、RR INT、INT K) { IF(L == R) 戻りL。 INT半ば=(L + R)>> 1。 INT TMP = T [L [RR]] - T [L [LL]。 もし(K <= TMP) { 戻りクエリ(L、中、L [LL]、L [RR]、K)。 } 他 { 戻りクエリ(MID + 1、R、R [LL]、R [RR]、K-TMP)。 } } メインINT(){ int型_。 scanf関数( "%のD"、&_)。 一方、(_--){ TOT = 0。 scanf関数( "%d個の%のD"、&N&K)。 root.clear(); 以下のために(INT i = 1; iが<= N; iは++){ ANS [I] = 0; scanf関数( "%d個"、&B [I])。 [I] = bの[I]; C [I] = I。 } ソート(A + 1、A + 1個の+ N)。 N =(A + 1、A + N + 1)ユニーク- (A + 1)。 root.push_back(ビルド(1、N))。 以下のために(INT i = 1; iが<= N; iは++){ insert1(ルート[I - 1]、B [I])。 } {ため(iは++; iがn = <I = 1 INT) int型のID = Cの[I]。 (1){一方 ANS [I] ++; INT KK = Query1を(ルート[分(N、ID + K)]、1、N、B [ID]) - Query1を(ルート[MAX(1、ID - K) - 1]、1、N、B [ID ]) - 1。 もし(KK == 0)ブレーク。 ID = Cの[クエリ(1、nは、ルート[MAX(1、ID - K) - 1]、根[分(N、ID + K)]、KK)]]。 IF(ANS [] ID [B]){ ANS [I] + = ANS [ID] [B]。 ブレーク; } } } {ため(iは++; iがn = <I = 1 INT) IF(I = N!)のprintf( "%dの"、ANS [I])。他のprintf( "%d個の\ n"は、ANS [I]); } } 0を返します。 }
宮殿の美しい値