146502025-01-25 15:08:08arnoldbeilandSzitakötő (50 pont)cpp17Wrong answer 6/5063ms3908 KiB
#include <iostream>
#include <vector>
using namespace std;

long long mod = 1000*1000*1000+7;

int main()
{
    int n, k;
    cin >> n >> k;

    vector<int> pow2(n+1);
    pow2[0] = 1;
    for (int i = 1; i <= n; i++)
        pow2[i] = pow2[i-1]*2 % mod;

    vector<long long> meret(n+1);
    for (int i = 1; i <= n; i++)
        cin >> meret[i];

    vector<long long> sp(n+1, 0); // részösszegek a meret-en
    for (int i = 1; i <= n; i++)
        sp[i] = sp[i-1] + meret[i];

    long long szorzo_bal = 0;

    // k balra kell induljon ha nem utolso...

    for (int i = 0; i <= k-1; i++) {
        // i = hányan indulnak jobbra közvetlenül k előtt
        // a (k-i-1). már balra indul ha még létezik
        int kmerete = sp[k] - sp[k-i-1];
        if (kmerete >= sp[k-i-1]) {
            int lehetosegek_elotte = pow2[max(0, k-1 - i - 1)];
            szorzo_bal = (szorzo_bal + lehetosegek_elotte) % mod;
        }
    }

    /*
        i > k esetén legyen

        dp[i] = az i, i+1, ... n lárvák olyan indulási lehetőségeinek száma,
                melyekkel nem alakul ki sum(meret[1], meret[i-1])-nél
                nagyobb vagy egyenlő lárva (aki felfalná a balra levőket)

        dp[n+1] = 1
        dp[n] = {
            0, ha meret[n] >= sum(meret[1]...meret[n])
            2, különben (indulhat balra vagy jobbra is)
        }

        dp[i] = {
            0, ha meret[i] >= sum(meret[1]...meret[i-1])
            különben: sum(
                // i balra indul:
                dp[i+1],

                // i jobbra indul:
                sum(dp[x+1], minden x-re, ahol
                    i < x <= n és
                    sum(meret[i]...meret[x]) < sum(meret[1], meret[i-1])
                )
            )
        }
        = sum(dp[x+1], minden x-re, ahol
            i <= x <= n és
            sum(meret[i]...meret[x]) < sum(meret[1], meret[i-1])
        )

        dp kiszámolható O(N*log(N)) időben, ha minden i-re binárisan
        keressük a legnagyobb x-et és a dp tömbön is részösszegeket
        számolunk menet közben
    */

    if (k == n) {
        cout << 2 * szorzo_bal % mod << "\n";
        return 0;
    }
    if (meret[n] >= sp[n-1]) {
        cout << 0 << "\n";
        return 0;
    }

    vector<long long> dp(n+2);
    vector<long long> dps(n+3); // dps[i] = dp[i] + dp[i+1] + ... + dp[n+1]
    dps[n+2] = 0;
    dp[n+1] = 1;
    dps[n+1] = dp[n+1] + dps[n+2];
    dp[n] = 2;
    dps[n] = dp[n] + dps[n+1];

    for (int i = n-1; i > k; i--) {
        int xbal = i, xjobb = n;
        while (xbal < xjobb) {
            int mid = (xbal+xjobb+1)/2;
            if (sp[mid]-sp[i-1] < sp[i-1])
                xbal = mid;
            else
                xjobb = mid-1;
        }
        if (sp[xbal] - sp[i-1] < sp[i-1]) {
            dp[i] = dps[i+1] - dps[xbal+2]; /* dp[i+1] + ... + dp[k+1] */
            dp[i] = (dp[i]+mod)%mod;
        }
        else
            dp[i] = 0;

        dps[i] = (dp[i] + dps[i+1]) % mod;
    }

    cout << (szorzo_bal * dp[k+1])%mod << endl;

    return 0;
}

SubtaskSumTestVerdictTimeMemory
base6/50
1Accepted0/01ms508 KiB
2Wrong answer0/063ms3892 KiB
3Accepted1/11ms316 KiB
4Accepted1/11ms316 KiB
5Accepted1/11ms316 KiB
6Accepted1/11ms316 KiB
7Accepted1/11ms316 KiB
8Wrong answer0/11ms316 KiB
9Wrong answer0/11ms316 KiB
10Wrong answer0/21ms316 KiB
11Wrong answer0/21ms316 KiB
12Wrong answer0/21ms316 KiB
13Wrong answer0/22ms316 KiB
14Wrong answer0/21ms512 KiB
15Wrong answer0/21ms508 KiB
16Wrong answer0/21ms316 KiB
17Wrong answer0/22ms316 KiB
18Wrong answer0/21ms348 KiB
19Wrong answer0/22ms316 KiB
20Wrong answer0/21ms316 KiB
21Accepted1/11ms500 KiB
22Wrong answer0/250ms3888 KiB
23Wrong answer0/248ms3908 KiB
24Wrong answer0/261ms3892 KiB
25Wrong answer0/257ms3892 KiB
26Wrong answer0/250ms2356 KiB
27Wrong answer0/234ms3892 KiB
28Wrong answer0/252ms3892 KiB
29Wrong answer0/241ms3892 KiB
30Wrong answer0/261ms3892 KiB
31Wrong answer0/246ms2360 KiB