每日"兩"題 題解

Allergy527發表於2024-03-13

每日“二”題

十年OI一場空,不開longlong見祖宗

目錄
  • 每日“二”題
    • A
    • B

A

題解:

最值問題,一個條件在變,考慮使用二分:
我們每次查詢一個可切的最大巧克力,二分判斷能不能這麼切即可。

C++程式碼
void solve() {
    int n, k, l = 1, r = 0, ans;
    cin >> n >> k;
    vector<pair<int, int>>qwq(n);
    for(auto &x : qwq) {
        cin >> x.first >> x.second;
        int mx = max(x.first, x.second);
        r = max(mx, r); //確定一個二分最大值,這裡其實也可以給一個很大的值減少程式碼量
    }
    while(l <= r) { //二分答案
        int mid = l + r >> 1;
        //check() 按一般背的板子來是寫一個 check() 我這裡為了方便直接寫這裡面了
        int tot = 0;
        for(auto x : qwq)tot += (x.first / mid) * (x.second / mid);
        if(tot < k)r = mid - 1;
        //check()截止
        else l = mid + 1;
    }
    cout << r;
}

B

題解:

我們建立一個字首和陣列,接著看一下里面同餘的有幾個數即可
(為什麼同餘就說明有倍數呢?這是因為:
如果兩數之間和不為k倍數,則餘數一定不同,容易可得自行證明吧XD

C++程式碼
void solve() {
    ll n, k, i, j,ans=0;
    cin >> n >> k;
    vector<ll>qwq(n + 1); //字首和陣列
    vector<ll>qaq(k + 1); //等效雜湊表->map
    for(i = 1;i <= n;++i) {
        cin >> qwq[i];
        //qwq[i] %= k; 這個並不重要,可以省略
        qwq[i] += qwq[i - 1]; //字首和,解題關鍵1
    }
    // 試了下暴力,並不能過
    for(i = 0;i <= n;++i)ans += qaq[qwq[i] % k]++; //同餘,解題關鍵2
    cout << ans;
}

相關文章