Монотонный анализ cf1276C--, мышление

/ * 
Предположим , строка <= седловины, сначала найти наибольшую площадь матрицы (строка, столбец), опять - таки независимо от введенного номера, и заполнить в 
текущей строке является строка, эта матрица в строке помещается до того же число раз, 
    после чего статистика , отсортировано по числу вхождений, а затем перечисление , нисходящей строке, по числу вхождений каждого числа рассчитываются в это время максимальной Col 
были записаны максимальная строка и столбец, то количество начинки, заполнить одинаковое количество часов наклонны для заполнения 
* / 
#include <бит / STDC H ++.>
 что используя  пространство имен STD;
 #define N 400005
 #define LL Long Long Int SUM [N], н-, A [N], НКТ; 
Map < INT , INT > MP;
 STRUCT Узел { Int V, CNT;} Р [N],
 INT CMP (& узел А, узел в &) { возвращение a.cnt < b.cnt;} Int bin_find ( INT Row) {



// 找到最后一个<= строка的位置
    INT L = 0 , R = CNT, ANS = 0 , в середине;
    в то время как (L <= R) { 
        середина = L + R >> 1 ;
        если (р [середина] .cnt <= строка) 
            ANS = середина L = середина + 1 ;
        то R = середина 1 ; 
    } 
    Вернуть анс; 
} 

INT ма [N], R, С; 
рядный INT Идентификатор ( INT я, INT к) { возвращение С * (i - 1 ) + J;} 
стека < INT> СТК;
недействительным решения () {
     для ( INT I = 1 ; я <= CNT; я ++ )
         для ( INT J = 1 , J <= мин (р [я] .cnt, R); j ++ ) 
            stk.push (р [я ] .в); 
    для ( Int к = 1 , K <= C, K ++ ) {
         INT I = 1 , J = K;
        в то время как (я <= R && J <= С) { 
            ма [ID (I, J)] = stk.top (); 
            stk.pop (); 
            ++ я, ++ J;
            если (I> R) перерыва;
            если (J> С) j- = С; 
        } 
    } 
    СоиЬ << R * C << ' \ п ' ; 
    соиЬ << R << "  " << C << ' \ п ' ;
    для ( Int I = 1 ; я <= R; я ++ ) {
         для ( INT J = 1 , J <= С; j ++ ) 
            соиЬ << ма [ID (I, J)] << "  " ; 
        ставит ( "" );

>> п;
    для ( Int I = 1 ; я <= п; я ++ ) { 
        Scanf ( " % D " , & [I]); 
        Т. пл [а [я]] ++ ; 
    } 
    
    Для (авто х: т.пли) { 
        р [ ++ CNT] .v = x.first; 
        р [CNT] .cnt = x.second; 
    } 
    
    Рода (р + 1 , р + 1 + CNT, CMP);
    для ( Int I = 1 ; я <= CNT; я ++ ) 
        сумму [I] = сумма [i - 1 ] +р [я] .cnt; 
    
    INT ANSR = 0 , ansc = 0 ;
    INT строка = ( INT ) SQRT (п);
    в то время как (строка) {
         INT р = bin_find (строка);
        INT Num = сумма [р] + строка * (cnt- р);
        INT Col = Num / строка;
        если (колонка> = строка && ANSR * ansc <столбец * строка) { 
            ANSR = строка; ansc = кол; 
        } 
        Грести - ; 
    } 
    
    R = ANSR, С = ansc; 
    решить(); // 填数
}
 / *
10000000002 
21000000000 
02100000000 
00210000000 
00021000000 
+12000 
01200 
00 120 
00 012 
20001 
* /

рекомендация

отwww.cnblogs.com/zsben991126/p/12111373.html