説明[CSP-Sシミュレーション96をテスト]

将来は書いていない問題の完全なソリューションのタイトルを変更する理由を借りることはできません......

A.合計

求$ \合計\和Iがj-1 $を+

柿は、それが......今年のPJはとても精神的にシンプルに配合された試験ではないではありません......

ピット1:不明率は、十分に除去する2における第1の乗算器限り逆元2、ではないかもしれません。

ピット2:取るために遅い1E18揚げ長い長い$ \ RIGHTARROWの$

#include <cstdioを> 
する#include <iostreamの> 
する#include <CStringの> 
する#include <ベクトル> 
名前空間STDを使用して、
typedefの長い長いLL。
LL、X、Y、XX、YY、MOD。
LL MUL(LLのB LL)
{ 
    LL RES = 0。
    (B)一方、
    { 
        (B&1)RES + = A、RES%= MOD場合 
        =(A + A)%MOD。
        B >> = 1。
    } 
    RESを返します。
} 
ベクトル<LL> FAC。
#define Fの
INT)(主
{ 
Fとの#ifdef 
    freopenは( "sum.in"、 "R"、STDIN)。
    freopenは( "sum.out"、 "W"、STDOUT)。
#endifの
    / * MOD = 1E9 + 7。
    coutの<< MUL(100000,3)<<
    scanf関数(」
    int型CNT = 1; 
    fac.push_back(X + XX)。
    fac.push_back(XX-X + 1)。
    fac.push_back(YY-Y + 1)。
    以下のために(INT i = 0; iは<3; I ++)
        IF(CNT && FAC [i]は%2 == 0)FAC [i]は、/ = 2、cnt--。
    LL ANS = 1。
    以下のために(; iは3 <; I = 0 int型私は++)
        ANS = MUL(ANS、FAC [i])と; 
    fac.clear(); CNT = 1。
    fac.push_back(Y + YY)。
    fac.push_back(XX-X + 1)。
    fac.push_back(YY-Y + 1)。
    以下のために(INT i = 0; iは<3; I ++)
        IF(CNT && FAC [i]は%2 == 0)FAC [i]は、/ = 2、cnt--。
    LLのRES = 1。
    以下のために(; iは3 <; I = 0 int型私は++)


        RES = MUL(RES、FAC [i])と; 
    (ANS + = RES)%= MOD。
    (ANS + = MOD)%= MOD。
    printf( "%LLDする\ n"、ANS)。
    / * ANS =(X + XX)*(X-X-X + 1)%MOD *(YY-Y + 1)%MOD *のINVの%のMOD。
    ANS + =(XX-X + 1)*(Y + 1 YY)%のMOD×(YY-Y + 1)%のMOD * INV%MOD; ANS%= MOD。
    ANS - =(XX-X + 1)*(YY-Y + 1)%MOD; ANS =(ANS + MOD)%MOD。
    printf( "%LLDする\ n"、ANS); * / 
    戻り0; 
}

 

ペアリングをグループ化するB.

グループの最大の合計値を作成することは明らかに、最大$ \回$ $ + $最大の第二位の$ \ $回二番目に大きい$ + ... $方法。

ここでは、簡単な証明について書くだけで、二対の場合を考えます。

それは強さが正の整数$ A> X、B>のy $である持っている必要がありますので、彼らは、$で、A、B、斧$で提供されます

だから、評価によって$ AB \回数の合計値とペア2 -ay-BX + XY $

$ AB \時間のクロスペア2 -ay-BX $

明らかに後者よりも元。

だから、長い貪欲スイープ権利として、グループに参加する時のような新しいグループに開いていません。

暴力は、その後、あらゆる種類またはバイナリ検索は確かではありません

このプロセスは右単調に拡張されているので、二つの点を考慮することができます

価格も二分法の範囲を削減する方法を見つけることが大いに必要であるしかし、一度ご確認ください

私たちは、違法な位置に第1の乗算器ができ、左マージンのために、その後に$ 1 <<(P-1)$、右の境界に2で割った$ 1 <<のp $

最悪時間計算量は$ O(N ^ 2 \ nをログ\)$です。

 

#include <cstdioを> 
する#include <iostreamの> 
する#include <CStringの> 
する#include <ベクトル> 
の#include <アルゴリズム> 
使用して名前空間std。
typedefの長い長いLL。
LL読み出す()
{ 
    LL X = 0、F = 1;チャーCH = GETCHAR()。
    (!isdigit(CH))、一方{IF(CH == ' - ')は、f = -1; CH = GETCHAR();} 
    ながら(isdigit(CH))X = X * 10 + CH-'0' 、CH = GETCHAR()。
    x * Fを返します。
} 
のconst int型N = 5E5 + 5。
int型のn; 
LLのM; 
LL [N]、B [N]。
ベクトル<LL>ノワ、nowb。
BOOLチェック(int型のL、R INT)
{ 
    ベクトル<LL> TMPA、TMPB。
    スワップ(ノワ、TMPA)、スワップ(nowb、TMPB)。
    (; I <= R; iが++ iがLに= INT)のために
        nowa.push_back([i])と、nowb.push_back(B [I])。 
        int型ミッド= L + R >> 1。
    ソート(nowa.begin()、nowa.end());ソート(nowb.begin()、nowb.end())。
    INT SZ = nowa.size(); LLのRES = 0。
    以下のために(INT I = SZ-1; I> = 0; i--)
    { 
        RES + =ノワ[I] * nowb [I]。
        IF(RES> M)戻り0; 
    } 
    1を返します。
} 
int型の検索(INT X)
{ 
    int型、P = 0。
    用(INT I = 0; I ++)
    { 
        P = I。
        (!(Xを確認し、分(xは+(1 << I)-1、N)));破る場合      
        IF(X +(1 << I)-1> = N)、ブレーク。
    } 
    int型L = X +(1 << P-1)-1、R =分(X +(1 << P)-1、N)、RESの= 1; 
    一方、(L <= R)
    {
    } 
    RESを返します。
        IF(チェック(X、MID))RES =中間、L =ミッド+ 1。
        他に、R =半ば1; 
} 
の#define F 
int型のmain()
{ 
#ifdefのFの
    freopenは( "pair.in"、 "R"、STDIN)。
    freopenは( "pair.out"、 "W"、STDOUT)。
#endifの
    )(= M読み取る; N =()を読み込みます。
    (; iが<= N I ++はiは1 = INT)のための
        [I] =(読み取り)
    (私は++; iが<= N I = 1 INT)のため
        )([I]読み取り= Bと、
    int型ANS = 0; 
    int型I = 1; 
    中にI =見つける(I)+ 1、ANS ++(私は= N <)。
    printf( "%d個の\ n"、ANS)。
    0を返します。
} 
/ * 
3 50 
6 7 6 
6 3 5 
* /

 

 

C.シティゲーム

cluckと

 

おすすめ

転載: www.cnblogs.com/Rorschach-XR/p/11779769.html