質問の意味:
図Nの1E5 = <、偶数ラインエッジ、通信ブロッククエリk番目の最大
アイデア:
恐怖はまだヒューリスティックは、爆発のトライメモリをマージする最後の時間を覚えているので、この点はまだ動的な回復で開いているため、セグメントツリー良い質問を組み合わせたエクササイズ
私は、ヒューリスティックマージスプレイ速くQAQを聞いてみてくださいすることを学びました
コード:
書式#include <iostreamの> の#include <cstdioを> する#include <アルゴリズム> 書式#include <cmath> の#include <CStringの> の#include < 文字列 > の#include <スタック> の#include <キュー> の#include <両端キュー> の#include < 設定 > #include <ベクトル> の#include <地図> の#include <機能> の#define FST最初 の#define SC第二 の#define PB一back の#define融点make_pair の#define MEM(A、B)のmemset(A、B、 sizeof(a)参照) #define LSON Lを、中間ルート<< 1つ の#define中間+ 1 rson、R、根<< 1 | 1 の#define LCルート<< 1つ の#define RCルート<< 1 | 1 の#define lowbit(X)(( X)および( - x))を使用して、名前空間STDを、 typedefをダブルデシベル。 typedefの長いダブルLDB。 typedefの長い長いLL。 typedefの符号なしの長い長いULL。 typedefのペア < int型、int型 > PI; typedefの対 <-1,11,11-> PLL。CONST DB EPS = 1E- 6 。 const int型 MOD = 1E9 + 7 。 const int型 MAXN = 1E5 + 100 。 const int型 MAXM = 6E6 + 100 。 const int型 INF = 0x3f3f3f3f 。 CONST dBのPI = ACOS( - 1.0 )。 INTのN、M。 int型Q; int型の LS [MAXN * 66 ]、RS [MAXN * 66 ]、DAT [MAXN * 66 ]。 int型のルート[MAXN]。 INT [MAXN]、ID [MAXN] INT [MAXN] F。 int型の検索(INT X){ 戻り F [X] == X X:[X] = F 検索(F [X])。 } INT TOT。 キュー < 整数 > プール。 int型新を(){ 場合(!pool.empty()){ int型のx = pool.front(); pool.pop(); リターンのx; } ++ TOT。 リターンTOT; } 無効デル(int型x)は{ 場合(!x)が復帰。 pool.push(X)。 返します。 } int型のビルド(int型 L、INTR、INT X){ int型ミッド=(L + R)>> 1 。 int型のp = 新しいです(); DAT [P] = 1 。 もし(L == R)リターンP。 もし(x <= MID)LS [P] = (L、中、X)を構築します。 他の RS [P] =ビルド(MID + 1 、R、X)。 リターンのp; } INTマージ(INT P、INT Q){ // 休暇P 場合(!P)リターンQ。 もし(!Q)リターンのp; LS [P] =マージ(LS [P]、LS [Q])。 RS [P] = マージ(RS [P]、RS [Q])。 DAT [P] + = DAT [Q]。 LS [q]は、RS [Q] = DAT [Q] = = 0 。 デル(Q)。 リターンのp; } int型の照会(int型のx、int型の L、int型の R、int型K){ int型ミッド=(L + R)>> 1 。 もし(L == R)戻りL。 もし(DAT [LS [X]]> = K){ 戻りクエリ(LS [x]は、L、中、K)。 } 他{ リターンクエリ(RS [x]は、中間+ 1、R、K- DAT [LS [X]])。 } } int型のmain(){ scanf関数(" %D%dの"、&N、&M)。 以下のために(int型 i = 1 ; iは= N <; iは++ ){ F [I] = I。 scanf関数(" %のD "、および[I])。 ID [[I] = I。 ルート[I] =(ビルド1 、nは、[I])。 } / * のための(I = 1をint型、iが<= N; iが++){ のprintf( " - %d個のルート::%Dを\ n"、私は、ルート[I])。 } 以下のために(INT I = 1; I <= TOT; iは++){ //のprintf( "%dの====%D%D%D \ n"は、I、LS [i]は、RS [i]は、DAT [私]); } / * ため(int型 I = 1 ; I <= M; iは++ ){ int型X、Y。 scanf関数(" %dの%のD "、およびX&Y)。 INTの T1 = (X)を求めます。 INTの T2 = (y)を見つけます。 もし(!T1 = T2){ ルート[T1] = マージ(ルート[T1]、根[T2])。 F [T2] = T1。 } } のscanf(" %dの"&Q); 一方(q-- ){ チャー OP [ 5 ]; int型のX、Y; scanf関数(" %sの%D%D 」、OP、およびX&Y); 場合(OP [ 0 ] = = ' Q ' ){ int型、T = (x)を見つける; 場合(DAT [ルート[T] <Y){のprintf(" -1の\ n "); 続ける;} 他のprintf(" %Dを\ n "、 ID [クエリ(ルート[T]、1、N、Y)])。 } 他{ int型の T1 = 見つける(X) INTの T2 = (y)を見つけます。 もし(!T1 = T2){ ルート[T1] = マージ(ルート[T1]、根[T2])。 F [T2] = T1。 } } } 戻り 0 。 } / * 5 1 4 3 2 5 1 1 2 7 Q 3 2 Q 2 1 B 2 B 1 5 Q 2 1 Q 2 4 Q 2 3 * /