8.9 NOIPシミュレーションテスト15都市(都市)+爆撃(爆弾)+じゃんけん(RPS)

残虐T3の範囲を考えると、私は最初の問題に退廃ピースソリューションを取ることにしました。

T1都市(都市)

包含と除外方法バッフル+

n個のグループにMの建設チームは、各グループが持っている必要があり、上限値、Cの合計(M-1、N-1)プログラムの種類とは見なされません。

K以上のI番目のグループ、オフ撥容量C(N、I)* C(MI * K-1、N-1)×K iは建設チームに出て対応し、残りMI * n個のグループとチームにkの構成は、各グループが少なくとも一つと結合しない考慮し、少なくとも二つのグループが存在するn個のパケットにこのI-kがK Iよりも大きいがあることを確認します。

書式#include <iostreamの> 
の#include <CStringの> 
の#include <cstdioを>
 に#define MOD 998244353
 の#define LL長い長い
 使って 名前空間はstdを、
LLのN、M、K、FAC [ 10001000 ]、INVの[ 10001000 ]、facinv [ 10001000 ]、ANS。
LL C(LLのX、LL Y)
{ 
    場合(Y> X)戻り 0 ;
    戻り FAC [X] * facinv [Y]%MOD * facinv [XY]%MOD。
} 
int型のmain()
{ 
    scanf関数(" %LLD%LLD%LLD "、&​​N、&M、およびK);
    もし(N>M){ 
        プット(" 0 " )。
        リターン 0 ; 
    } 
    FACが[ 0 ] = 1 ; facinv [ 0 ] = 1 ; INV [ 1 ] = 1 以下のためにint型 i = 1 ; iは= MAX(N、M)<; I ++のを){
         場合(I =!1)INV [I] =(MOD-MOD / I)* INV [MOD%I]%MOD。
        FAC [i]は = FAC [I- 1 ] * I%MOD。
        facinv [I] = facinv [I- 1 ] * INV [I]%MOD。
    } 
    のためにint型 i = 1 ; iがn = <; iは++ ){
         場合(I&1)ANS =(ANS + C(N、I)* C(MI * K- 1、N- 1))%MOD。
         ANS =(ANS-C(N、I)* C(MI * K- 1、N- 1)+ MOD)%MOD。
    } 
    のprintf(" %のLLDを\ n "、(C(M- 1、N- 1)-ans + MOD)%のMOD)。
    リターン 0 ; 
}
シティ

 

T2の爆撃(爆弾)

受験間違った多くの質問が、私はそれを行うには間違っていませんでした(廃棄物です)

限りパスが到達することができる動きがあるように、我々は、(いくつかのポイントが一緒に塊完成図は、最長の鎖を見つけるために、新しいポイントを構築した後に収縮、各点の深さは、親ノード点+奥行き寸法でなければならない、tarjanが縮小指し)、topu要求最長鎖、またはDFS(DFSなく容易Tと思われます)。

書式#include <iostreamの> 
の#include <cstdioを> 
する#include <キュー>
 使用して 名前空間はstdを、
構造体ノード
{ 
    int型、NXTに、
} H [ 4001000 ]、HH [ 4001000 ]。
int型 N、M、NXT [ 4001000 ]、TOT、TET、CNT、[DFN 1001000 ]、[低1001000 ]、S [ 1001000 ]。
int型の上部、NUM、whosは[ 1001000 ]、SZ [ 1001000 ]、デュ[ 1001000 ]、DEP [ 1001000 ]、ANS、NX [ 4001000 ]。
ブール値 である [ 1001000];
INTの最大値(INT X、int型のY)
{ 
    戻り X> Yの?X:Y。
} 
ボイド追加(int型のx、int型のY)
{ 
    H [ ++ TOT] .TO = Y。
    H [TOT] .nxt = NXT [X]。
    NXT [X] = TOT。
} 
ボイドの生成物(int型のx、int型Y)
{ 
    HH [ ++ TET] .TO = Y。
    HH [TET] .nxt = NX [X]。
    NX [X] = TET。
} 
ボイド tarjan(INTX)
{ 
    [X] DFN =低[X] = ++ CNT。
    S [ ++トップ] = xと; ある [X] = 1 以下のためにint型 I = NXT [X]を、I; I =をH [i]を.nxt){
         int型、Y =をH [i]は.TO。
        もし(!DFN [Y]){ 
            tarjan(Y)。
            低[X] = 分(低[x]は、低[Y])。
        } 
        そう であればある低[Y])を[X] = 分(DFN [Y]、[x]は低いです)。
    }     
    もし(DFN [X] == 低[X]){ 
        NUM ++ しばらく1 ){
             int型 TMP = S [top-- ]。
            ある [TMP] = 0 ; 
            玉葉[TMP] = NUM。
            SZ [NUM] ++ ;
            もし(X == tmp)にブレーク
        } 
    } 
} 
ボイドtopu()
{ 
    キュー < INT > Q。
    int型 I = 1 ; I <= NUM iが++ 場合(DU [I] == 0)q.push(I)、DEP [I] = SZ [i]は、ANS = MAX(ANS、DEP [I ]);
    同時に(q.size()){
         int型のx = q.front(); q.pop()。
        以下のためにint型 I = NX [X]を、I; I =のHH [i]が.nxt){
             int型、Y =のHH [i]は.TO。
            デュ[Y] - 
            DEP [Y] = MAX(DEP [Y]、DEP [X] + SZ [Y])。
            ANS = MAX(ANS、DEP [Y])。
            もし(!q.push(Y)デュ[Y])。
        } 
    } 
} 
int型のmain()
{ 
    scanf関数(" %D%dの"、&​​N、&M)。
    int型のuを、V。
    以下のためのint型I = 1 ; I <= M; iは++ ){ 
        scanf関数(" %d個の%のD "、&​​U、およびV)。
        (V、U)を追加します。
    } 
    のためにint型 I = 1は iが++; iがn = < であれば(!tarjan(I)DFN [I])。
    以下のためにint型私= 1 ; iが<= N; iが++ ){
         ためINT J = NXT [I]; J; Jは= H [J] .nxt){
             int型、Y = H [J] .TO。
            もし(whosは[I] =!玉葉[Y]){ 
                広告(玉葉[I]、whosは[Y])。
                デュ[whosは[Y]++ ; 
            } 
        } 
    } 
    topu()。
    printf(" %d個の\ n " 、ANS)。
}
爆弾

 

おすすめ

転載: www.cnblogs.com/jrf123/p/11328044.html