Amami’s competitive diary

PG BATTLE 2021 せんべい参加記

はじめに

一昨年のましゅまろ、去年のせんべいに続き今年もせんべいで3完以上を目指していましたがBの考察に時間をかけすぎて2完に終わりました。

A問題

概要

確率 p で勝利する勝負を7回行った時に、勝ち越す確率はいくらか。

考察

n 回のうち、確率 p の事象が k 回起こる確率は
 _n C_k * p^{k} * (1 - p)^{n - k}
となり、この k4 ~ 7 まで総和を取ればいいので、結果的には
 \sum_{k=4}^7  \{_7 C_k * p^{k} * (1 - p)^{7 - k}\}
を求めればいいことになります。

実装

#include<bits/stdc++.h>
using namespace std;

// Combination
long long nCr(long long n, long long r) {
    long long x = 1, y = 1;
    for(long long i = 0; i < r; i++) {
        x = x * (n - i);
        y = y * (i + 1);
    }
    return x / y;
}

int main()
{
    double p;
    cin >> p;
    p /= 100;
    double q = 1.0 - p;
    double ans = 0;
    for(int i = 4; i <= 7; i++) {
        ans += nCr(7, i) * pow(p, i) * pow(q, 7 - i);
    }
    cout << fixed << setprecision(15) << ans * 100 << endl;
    return 0;
}

B問題

概要

t 個のクエリに答える。
各クエリに対して n , m が与えられる。
この時、2重辺や自己辺を作らずに n 頂点 m 辺の無向グラフを構築した時の、連結成分の数の最小値と最大値を求める。

例 : 4 頂点 3 辺の場合

最小値は以下のように辺をつないだ場合の 1 になります

f:id:amami0522:20211023213703p:plain

最大値は以下のように辺をつないだ場合の 2 になります

f:id:amami0522:20211023213933p:plain

考察

最小値に関しては簡単で、連結成分が n ある状態から辺を 1 本増やすと連結成分を 1 減らすことができるので基本的には n-m になります。
ただ、1 未満になることはないので、1n-m の大きい方を出力すればいいです。

次に最大値です。私は、連結成分を X にすることができるか、ということへの二分探索を行いました。
連結成分が X になるということは、mn-X+1 頂点の完全グラフの辺の数より少なければ良いので
m\leq\frac{(n-X+1)(n-X)}{2}
を満たせばよいということになります。

実装

#include<bits/stdc++.h>
using namespace std;

// n頂点m辺で連結成分がmid個にできるか
bool isOk(long long n, long long m, long long mid) {
    long long x = n - mid + 1;
    long long sum = x * (x - 1) / 2;
    return m <= sum;
}

int main()
{
    int t;
    cin >> t;
    while(t--) {
        long long n, m;
        cin >> n >> m;
        long long ans1, ans2;
        // 最小値
        ans1 = max(1LL, n - m);
        // 最大値
        long long ok = ans1;
        long long ng = n + 1;
        while(abs(ok - ng) > 1) {
            long long mid = (ok + ng) / 2;
            if(isOk(n, m, mid)) ok = mid;
            else ng = mid;
        }
        ans2 = ok;

        cout << ans1 << " " << ans2 << endl;
    }
    return 0;
}

おわりに

学生として出られるのは今年で最後ですが来年からも時間があれば出場出来たらなと思います。