その答えを探します

2019マルチ大学研修コンテスト3

トピック住所:http://acm.hdu.edu.cn/showproblem.php?pid=6609

質問が意図される:配列と、i番目の要素について、各iについて、残りの除去、i番目及び加算i番目の再以前の数kの前に除去置き、最大の要件をkおよび、桁数mを超えた残りの桁の、すなわち、除去して、各Iのために除去する必要がある前に、以下Mの最小値にデジタル出力の数を追加し、データの大規模な範囲は、離散化する必要があるためありません

アイデア:+個別のセグメントツリー

離散セグメントツリーの前の位置と間隔の数と直接的部MAの数の合計よりも少ない各区間[I]のためのメンテナンス間隔にそれぞれI、I-1どの要素用その答えに含まれ、下向きの最終集計の答えよりも大きいために答え、番号を削除する理由後でPEの最終的な数を知ることができませんスペースを入れずに、出力形式に注意を払うことである-1- Iで、見続けています。

 

// 
// 2019年7月29日ONマイルによって作成されます。
 // 
// HDUマルチT7スクール3日目は、2019
 // 個別のセグメントツリー+
 // 出力フォーマット:各番号の後ろにスペース、出力の各行の後にスペースがあります

#include <ビット/ STDC ++ H.> の#define LIDのID << 1つの。
 の#define RID ID 1 << | 1。
 使用した名前空間STD; 
typedefの長いロングLL;
 のconst int型 MAXN = 200005 ; 構造体民{
     int型CNT、ヴァル、IDと、
}; ストラクトノード{
     int型のCOUNT、ID、Lは、Rが、
    LL SUM; 
}; BOOL

   





CMP1(民、民b)は{
     戻り a.val == b.val?a.id <b.id:a.val < b.val。
} 

ブールCMP2(NUM、テンキーb)は{
     戻り a.id < b.id。
} 

構造体SegmentTree { 
    LL N、M。
    NUM NUM [MAXN]。
    ノードTR [MAXN << 2 ]。

    ボイドのinit(int型のn、int型M){
         この - > N = N、 - > M = M。
        以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
            scanf関数(" %dの"、&NUM [I] .val)。
            NUM [I] .ID = iは、
        } 
        ソート(NUM + 1、NUM + N + 1 、CMP1)。
        以下のためにint型 i = 1 ; iが<= N; iは++)NUMを[I] .CNT = I。
        ソート(NUM + 1、NUM + N + 1 、CMP2)。
        ビルド(11 、N)
    } 

    ボイドビルド(int型 ID、int型の L、INT R){ 
        TR [ID] .L = L、T R [ID] .R = R。
        TR [ID] .SUM= TR [ID] .count = 0 もし(TR [ID] .L == TR [ID] .R){
             返します
        } 
        INT半ば=(L + R)>> 1 
        (蓋、L、ミッド)を構築。
        構築(RID、ミッド + 1 、R); 
        TR [ID] .SUM = TR [蓋] .SUM + T R [RID] .SUM。
    } 

    ボイド更新(int型 ID、int型 POSを、int型CNT){
         場合(TR [ID] .L == TR [ID] .R && TR [ID] .L == POS){ 
            TR [ID] .SUM = NUM [CNT] .val。TR [ID] .count = 1 返します
        } 
        INT半ば=(TR [ID] .L + TR [ID] .R)>> 1 もし(POS <= MID)更新(蓋、POS、CNT);
        他の更新(RID、POS、CNT); 
        TR [ID] .SUM = TR [蓋] .SUM + T R [RID] .SUM。
        TR [ID] .count = TR [蓋] .count + T R [RID] .count。
    } 

    INTクエリ(INT ID、LL合計){
         場合(TR [ID] .SUM <=和)戻りTR [ID] .count。
        もし(TR [ID] .L == TR [ID] .R)戻り TR [ID] .SUM <= 和。
        もし(TR [蓋] .SUM> =合計)リターンクエリ(蓋、合計)。
        他に 返す .count +クエリ(RID、sum- TR [蓋]をTR [蓋] .SUM)。
    } 

    ボイドは、{()を解く
         ためのint型 I = 1を iが++; iが<= N ){ 
            (printfの" %のD "、I- 1 -query(1、M [i]は.val)NUM)。
            アップデート(1 、NUM [I] .CNT、NUM [I] .ID)。
        } 
        プット("" )。
    } 
}。

SegmentTreeツリー; 


INT のmain()
{ 
    int型Q。
    scanf関数(" %d個"、&Q)。
    一方、(Q-- ){ 
        LL N、M。
        scanf関数(" %のLLDの%のLLD "、&​​N、&M)。
        tree.init(N、M); 
        tree.solve(); 
    } 
    戻り 0 
}
コードの表示

 

  

おすすめ

転載: www.cnblogs.com/mile-star/p/11267416.html