BZOJ 2733 [HNOI2012]ネバーランド(セグメントツリーヒューリスティック合計重量+互いに素なセット)

質問の意味:

図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 
 * /

 

おすすめ

転載: www.cnblogs.com/wrjlinkkkkkk/p/10977311.html