コード:
#include <ビット/ STDC ++ H> 名前空間STDを使用して、 typedefの長い長いLL。 const int型MAXN = 100003; 名前空間IO { ボイドsetIO(文字列s){ = S内の文字列+ "です。"; 文字列アウト= sの+ "アウト。"; freopenは(in.c_str()、 "R"、STDIN)。 freopenは(out.c_str()、 "W"、STDOUT)。 } のchar *のP1、P2 *、BUF [100000]。 #define NC()(P1、P2 == &&(P2 =(P1 = BUF)+関数fread(BUF、1,100000、STDIN)、P1 == P2)EOF:* P1 ++) int型RD(){ int型のx = 0 ; チャーC = NC()。 一方、(C <48)C = NC()。 一方、(C> 47)x =(((X << 2)+ X)<< 1)+(C ^ 48)、C = NC()。 Xを返します。 [MAXN]編曲:int型。 構造体スプレイ{ の#define LSONのCH [X] [0] の#define rson CH [X] [1] スタック<整数> S。 int型CNT、TP。 INT CH [MAXN] [2]、F [MAXN]、ヴァル[MAXN]、SIZ [MAXN]、タグ[MAXN]、鍵[MAXN]。 ボイドのinit(){ ため(INT I = 1; I <MAXN; ++ I)S.push(I)。 } INT newnode(){ int型のx = S.top(); S.pop()。 Xを返します。 } ボイドマーク(int型のx、int型のD){ ヴァル[X] - = D、タグ[X] + = D。 } INT GET(INT X){ 戻りCH [[X] F] [1] == X。 } ボイド押し上げ(INT X){ SIZ [X] = SIZの【のLSON] + SIZ [rson] +1。 } ボイドプッシュダウン(int型X){ IF(タグ[X])マーク(LSON、タグ[X])、マーク(rson、タグ[X])、タグ[X] = 0; } ボイド回転(INT X){ int型古い= F [x]は、(X)を取得=れ、= F [古い]を折ります。 CH [古い] [] = CHを[X] [^ 1]、F [CH [古い] [た] =古いです。 CH [X] [X]倍= F、古い、F [古い] = xを= [どの^ 1]。 IF(倍)CH [倍] [CH [倍] [1] ==古い] = xと; 腕立て伏せ(旧)、腕立て伏せ(x)は、 } ボイドスプレイ(INT X、INT&タール){ int型、U = F [タール]、FA。 ((FA = F [X])^ U(x)が回転する)ための IF(F [FA] ^ U) 回転((X)FA取得==)(FAを得る:X) タール= X; } (X){ながら プッシュダウン(X)。 int型のプレ(INT V){ INT X =ルート、再= 0。 IF(ヴァル[X] <= V)再= X、X = rson。 他のx = LSON。 } 戻り再。 } INT NXT(INT V){ int型のx =ルート、再= 0。 (X){ながら プッシュダウン(X)。 (ヴァル[X]> = V)再= X、X = LSON場合; 他のx = rson。 } 戻り再。 } ボイドビルド(INT&X、INT FF、INT L、int型R){ X = newnode()。 INT半ば=(L + R)>> 1。 F [X] = FFの、ヴァル[X] =のARR [中間]、SIZ [X] = 1。 IF(L <MID)ビルド(LSON、X、L、ミッド1)。 IF(R> MID)ビルド(rson、X、中間+ 1、R)。 突き上げ(X)。 } INT {(INT&X、INT FF、INT K)を挿入 (!X){場合 )(X = newnode。 F [X] = FFの、ヴァル[X] = K、SIZ [X] = 1。 突き上げ(X)。 Xを返します。 } プッシュダウン(X)。 INT A =(CH [X] [K>ヴァル[X]、X、k)を挿入します。 突き上げ(X)。 返します。 } 無効DFS(int型x)は{ (!x)の場合はリターン。 プッシュダウン(X)。 キー[++ TP] = valの[X]。 IF(LSON)DFS(LSON)。 IF(rson)DFS(rson)。 S.push(X)。 CH [X] [0] = CHが[X] [1] Fを= [X] = valの[X] = SIZ [X] =タグ[X] = 0; int型X =根; } INT k番目(INT K){ (1){つつ プッシュダウン(X)。 もし(K> SIZの【のLSON]){ K - =(SIZの【のLSON] +1)。 (K == 0)はヴァルを返す場合、[X]。 他のx = rson。 } そうでなければ、X = LSON。 } } ボイドは(int型K){解決 INT PR =プレ(K)、NX = NXT(K << 1)。 もしマーク(根、K)(PR!)。 他に{場合(NX!) スプレイ(PR、根); INT A = CH [ルート] [1]。 CH [ルート] [1] = F [CH [ルート] [1] = 0; 突き上げ(ルート)。 TP = 0; DFS(A)。 {(; I <= TP ++ iは1 = INT)のために INTのCC =インサート(根、0、キー[I] -k)。 IF(I%6 == 0)スプレイ(CC、根)。 } } 他{ スプレイ(PR、根)、スプレイ(NX、CH [ルート] [1])。 = CH [CH [ルート] [1] [0] INT。 CH [CH [ルート] [1] [0] = 0、押し上げ(CH [ルート] [1])。 TP = 0、DFS(A)。 マーク(CH [ルート] [1]、K)。 以下のために(INT I = 1; I <= TP; ++ I){ int型のCC =インサート(根、0、キー[I] -k)。 IF(I%6 == 0)スプレイ(CC、根)。 } } } の#undef LSON INTメイン(){ 使用して名前空間IO。 の#undef rson } TR。 // setIO( "入力"); tr.init(); N INT、M。 N = RD()、M = RD()。 )([I] = RDをARRため(++ I; iは= N <I = 1 INT)。 ソート(ARR + 1、ARR + 1 + N)。 tr.build(根、0,1、N)。 用(int型CAS = 1; CAS <= M; ++ CAS){ int型のOP、K。 OP = RD()、K = RD()。 IF(OP == 1)のprintf( "%d個の\ n"、tr.kth(K))。 他tr.solve(K); } 0を返します。 }