教育Codeforcesラウンド81

E

効果の対象に

順列所与P P、および配列A Aは右に中間位置から配置を必要とする、配列の各位置のためのエネルギー値を表し、両者を左、右に左に移動するいくつかの数、いくつかの適切な数、左に移動するので、すべての値のすべての値より少ない左に右より場所を移動するコストのためのエネルギー値。最小のエネルギー値は、必要な条件を満たすために必要。何のナンバーワン側が存在しない場合、我々はまた、それが上記の条件を満たしていることを信じていることを注(偽前提命題は、全体の事本当です)。

溶液:
まず、最終的な答えは間違いなく最初の2セットを知っていることは、空のセットのいずれか【1〜K]であり、第二は、[K + 1〜N]です。

列挙kに持っているだけでなく、我々はKのために、我々は接頭辞と一緒に仕事をし、我々は最終的に残ってますようKさん(のために費やしたコストの異なるセットを表しできることがわかったときに、カットポイントは、からカットする必要があります列挙するために、我々はそう1 2 3 4 ...)これです。

例えば、我々は= 1 K、それが右の2〜N、K = 3であり、左の組の最終的な形を示し、最終的なフォーム123を左右4〜Nの二組のために表します。

kの各々は、次の点をカット変換の最小コストをとるように選択されるという条件で

私たちは、トラバースのためのポイントをカット想定している現在のカットポイントI、iqwe、P UO ..

iが5は、[1,4]ここで[5]重量5重量-aを追加する必要があり、K + 1 = 5 1〜4 =これらはKとなる示し、それは右内から設定されるべきであると仮定= 、セットを過ごすために右の彼を含める前にマイナスオフセット[5]である必要があり、ここで[N]、[5]ので、コレクションのコスト上昇の左側に

それはあなたが5をカット絵の2種類の形成についてです、あなたはK = 4を選択し、自由に残されたが、我々は5余分なサプリメント1234年の支出を取得しなければならなかった、または右の良い5 6 7 ..nを過ごすことを選択しましたさ予算の良い、5には、この時間は、削除を過ごすために準備しました。

4 [5]ここから直接追加しないで、なぜあなたは、事前に12を過ごすために、我々はカットポイントは、あなたがこのうち534に戻ってカットすることができ、ある移動しますので、123は、それを持っています。

私たちは、ツリーラインのメンテナンス間隔ですので、あなたは右のk、5月から何かを取る必要がないかもしれないので、各ポイントは、nはそうリットル= 0、R = nは、代わりに、L = 1であり、R =(kの値をとりますビン分を取るために、)分割する2つの完璧を開始します。

#include <ビット/ STDC ++ H> 
に#define LL長い長い
名前空間stdを使用。
INT、N、P [200005]、[200005]、ID [200005]。
LL MINV [800005]、ヴァル[200005]、ADDV [800005]。
ボイド押し上げ(INT RT)
{ 
    MINV [RT] =分(MINV [RT << 1]、MINV [RT << 1 | 1])。
} 
ボイドプッシュダウン(INT RT)
{ 
    IF(ADDV [RT])
    { 
        LL T = ADDV [RT]。
        MINV [RT << 1] + = T; MINV [RT << 1 | 1] + = T。
        ADDV [RT << 1] + = T; ADDV [RT << 1 | 1] + = T。
        [RT] = 0 ADDV。
    } 
} 
ボイドビルド(int型RT、INT L、INT r)を
{ 
    INT半ば=(L + R)>> 1。
    IF(L == R){MINV [RT] = valの[L];リターン;}  
    ビルド(RT << 1、L、MID);ビルド(RT << 1 | 1、
    押し上げ(RT)。
}
ボイド追加(int型RT、int型のL、R INT、INT QL、QR INT、LL V)
{ 
    int型ミッド=(L + R)>> 1。
    IF(QL <= L && R <= QR)
    { 
        ADDV [RT] + = V; MINV [RT] + = V。
        リターン; 
    } 
    プッシュダウン(RT)。
    IF(QL <= MID)(RT << 1、L、中間、QL、QR、V)を加えます。
    場合(QR>半ば)を追加(RT << 1 | 1を、ミッド+ 1、R、QL、QR、V); 
    突き上げ(RT)。
} 
int型のmain()
{ 
    scanf関数( "%のD"、&N); 
    以下のために(INT I 1 =; I <= N; ++ I)のscanf( "%d個"、&P [i])と、ID [P [I] = I。
    以下のために(INT I 1 =; I <= N; ++ I)のscanf( "%dの"、および[I])。
    以下のために(INT I 1 =; I <= N; ++ I)のval [I] = valの[I-1] + [ID [I]]。
    ビルド(1,0、n)は、
    LL ANS =(LL)1E18。
        (1,0、N、O、P [I] -1、[I])を追加します。
        (1,0、N、P [i]は、N、-a [I])を追加します。
// COUT << MINV [1] << ENDL。
        ANS =分(ANS、MINV [1])。
    } 
    COUT << ANS << ENDL。
}

  D

提供G C D A M = X GCD(A、M)= X、あるA = K 1 X M = K 2 Xが
知っていることができるG C D A + B Mを= Xであり、A + B = K 3
質問は今閉じた間隔で、となる[ K 1 K 1 + K 2 - 1 ]何インナーK2互いに素は
、プレフィックス問題に分割しました包含および除外の因子のN素因数分解

書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <cmath> 
の#include <cstdioを> 
する#include <CStringの> 
の#include <cstdlib> 
書式#include <キュー> 
std名前空間を使用しました。
#define MEM(B)のmemset(A、B、はsizeof())
のtypedef長い長LL。
ペアのtypedef <int型、int型> PII。
#define X最初の
Y第二の#define 
インライン読み取りLL()
{ 
    LL X = 0、F = 1; CHAR C = GETCHAR()。
    一方、(isdigit(C)!){IF(C == ' - ')= -1 F; C = GETCHAR();} 
    ながら(isdigit(c)参照){X = X * 10 + C-'0' 。 C = GETCHAR();} 
    戻りX * F。
} 
int型のT。
LL、M、X、K1、K2。
LLのGCD(LLのA、LL b)は{戻りB == 0?:GCD(B、%のB);} 
の#include <
ベクトル<LL> PME。
LLのcount_prime(LLのX、LL N){ 
    pme.clear()。
    LL I、J。
    以下のために(I 2 =、iは、* I <= N; I ++)
        IF(N%I == 0){ 
            pme.push_back(I)。
            一方、(N%I == 0)N / = I。
        } 
    IF(N> 1)pme.push_back(N)
    LL和= 0、値、CNT。
    以下のための(iは= 1; I <(1 << pme.size()); I ++){ 
        値= 1。
        CNT = 0; 
        (; J <pme.size(); J = 0 J ++)用{ 
            IF(I&(1 << J)){ 
                値* = PME [J]。
                CNT ++; 
            } 
        } 
        もし(CNT&1)
            合計+ = X /値。
        他sum- = X /値。
    }
    X-合計を返します。
} 
メインINT() 
{ 
    T =(INT)を(読み取り); 
    一方、(T--)
    { 
        =を読み取る(); M =)(読み取ります。
        X = GCD(M)。
        K1 = A / X; K2 = M / X。
        COUT << count_prime(K2 + K1-1、K2)-count_prime(K1-1、K2)<< ENDL。
    } 
    0を返します。
}

  C

・あなたに2つの文字列を与えます

sが、トン、シーケンスは、文字列を使用するたびに必要な設定トンの、最も安価な数。

 

集合P R&LT E [ I ]の文字を表し、私は私最も早く出現位置、S U F [ I ]を[ J ]  を表し、最初を表し、I iビット文字、文字J J最も早い位置、このことができるO 26でありますN- 前処理アウトO(26N)は
、それの周りに交差ホップ直上繰り返します

書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <cmath> 
の#include <cstdioを> 
する#include <CStringの> 
の#include <cstdlib> 
書式#include <キュー> 
std名前空間を使用しました。
#define MEM(B)のmemset(A、B、はsizeof())
のtypedef長い長LL。
ペアのtypedef <int型、int型> PII。
#define X最初
の#define Y第二
のインラインint型リード()
{ 
    int型のx = 0、F = 1; CHAR C = GETCHAR()。
    一方、(isdigit(C)!){IF(C == ' - ')= -1 F; C = GETCHAR();} 
    ながら(isdigit(c)参照){X = X * 10 + C-'0' 。 C = GETCHAR();} 
    戻りX * F。
} 
CONST INT MAXL = 100010。
T int型; 
チャーS [MAXL]、T [MAXL]。
INTプレ[30]、SUF [MAXL] [30]; //事前(I)表示字符I最早出现位置、SUF(i、j)の表示在I字符后、字符J最早出现位置
INT)(主
{ 
    T =)(読み取ります。
    (T--)一方
    { 
        MEM(予め、42); MEM(SUF、42)。
        scanf関数( "%S%S"、S、T)。
        INT L1 = STRLEN(S)、L2 = STRLEN(t)は、CNT = 0、OK = 0。
        用(INT iは= 0; I <L1; I ++)[I] [S - [A ']事前=分(PRE [S [I] - [A']、I)。
        SUF [i]は[S [I + 1] - ''] = I + 1について(; I <L1-1 I ++ INT iが= 0)。
        (; I> = 0 i-- INT I = L1-1)用
            のための(INT J = 0であり、j <26; J ++)SUF [I] [J] =分(SUF [I]、[J]、SUF [I + 1] [J])。
        (; I <L2 iが0 = INT)のために
        { 
            ++ CNT。
            INT POS =プレ[T [i]が' - ']; I ++。
            IF(POS> = L1){OK = 1;ブレーク;}
            一方、(SUF [POS] [T [i]が' - ' <L1)POS = SUF [POS] [T [i]が' - ']、I ++。
        } 
        のprintf( "%d個\ n"は、CNT)であれば(OK!)。
        他のprintf( "%d個\ n"は、 - 1); 
    } 
    0を返します。
}

  B

超ロングカードでの真のブレークスルーは、まずあなたが01で構成される文字列を与え、あなたは多くの接頭辞を失う満たすことができる方法でお聞きし、番号0をこの文字列のコピーを使用し続けると、無限に長い文字列を貼り付けることができるようになります1×所定数に等しいです。

書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <cmath> 
の#include <cstdioを> 
する#include <CStringの> 
の#include <cstdlib> 
書式#include <キュー> 
std名前空間を使用しました。
#define MEM(B)のmemset(A、B、はsizeof())
のtypedef長い長LL。
ペアのtypedef <int型、int型> PII。
#define X最初
の#define Y第二
のインラインint型リード()
{ 
    int型のx = 0、F = 1; CHAR C = GETCHAR()。
    一方、(isdigit(C)!){IF(C == ' - ')= -1 F; C = GETCHAR();} 
    ながら(isdigit(c)参照){X = X * 10 + C-'0' 。 C = GETCHAR();} 
    戻りX * F。
} 
CONST INT MAXN = 100010。
INT T、N、X、P0 [MAXN]、P1 [MAXN]、あらかじめ[MAXN]、MAX。
チャーS [MAXN]。
    T = READ()。
    (T--)一方
    { 
        MEM(P0,0)、MEM(p1,0)、MEM(PRE、0); 
        N =読み取る(); X =読み取り()。
        int型CNT = 0; 
        scanf関数( "%s"は、S + 1)。
        (; <I = N; INT iは1 = ++ i)に対するP0 [I] = P0 [I-1] +(S [I] == '0')、P1 [I] = P1 [I-1] + (S [I] == '1')、予め[I] = P0 [i]は-p1 [I]。
        (x == 0)CNT = 1の場合。
        (予備[N])であれば
        { 
            ((X-PRE [I])%プレ[N] == 0 &&(X予め[i])とIF /用に(++ I; <I = N INT iは= 1)事前[N]> = 0)CNT ++。
        } 
        { 
            ため(INTがI = 0; <I = N; ++ i)から(X ==事前[i])とCNT ++場合。
        } 
        (PRE [N] && CNT!)のprintf( " - 1 \ n")であれば、
        他のprintf( "%d個\ n"は、CNT);
}

  

 

おすすめ

転載: www.cnblogs.com/hgangang/p/12244476.html