Submission #675653

#TimeUsernameProblemLanguageResultExecution timeMemory
675653LucaIlieBootfall (IZhO17_bootfall)C++17
13 / 100
1051 ms8456 KiB
#include <bits/stdc++.h>

using namespace std;

const int maxN = 500;
const int maxS = 500 * 500;

using cd = complex<double>;
const double PI = acos(-1);

void fft(vector<cd> & a, bool invert) {
    int n = a.size();
    if (n == 1)
        return;

    vector<cd> a0(n / 2), a1(n / 2);
    for (int i = 0; 2 * i < n; i++) {
        a0[i] = a[2*i];
        a1[i] = a[2*i+1];
    }
    fft(a0, invert);
    fft(a1, invert);

    double ang = 2 * PI / n * (invert ? -1 : 1);
    cd w(1), wn(cos(ang), sin(ang));
    for (int i = 0; 2 * i < n; i++) {
        a[i] = a0[i] + w * a1[i];
        a[i + n/2] = a0[i] - w * a1[i];
        if (invert) {
            a[i] /= 2;
            a[i + n/2] /= 2;
        }
        w *= wn;
    }
}

vector<int> multiply(vector<int> const& a, vector<int> const& b) {
    vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end());
    int n = 1;
    while (n < a.size() + b.size())
        n <<= 1;
    fa.resize(n);
    fb.resize(n);

    fft(fa, false);
    fft(fb, false);
    for (int i = 0; i < n; i++)
        fa[i] *= fb[i];
    fft(fa, true);

    vector<int> result(n);
    for (int i = 0; i < n; i++)
        result[i] = round(fa[i].real());
    return result;
}

int v[maxN + 1];
bitset<maxS + 1> pos1n[maxN + 1], posn1[maxN + 2];
bitset<maxS + 1> pos, tim, timTemp;

int main() {
    int n, s = 0;

    cin >> n;
    for ( int i = 1; i <= n; i++ )
        cin >> v[i], s += v[i];

    pos1n[0][0] = true;
    for ( int i = 1; i <= n; i++ )
        pos1n[i] = (pos1n[i - 1] | (pos1n[i - 1] << v[i]));
    posn1[n + 1][0] = true;
    for ( int i = n; i >= 1; i-- )
        posn1[i] = (posn1[i + 1] | (posn1[i + 1] << v[i]));

    if ( s % 2 != 0 || !pos1n[n][s / 2] ) {
        cout << 0;
        return 0;
    }

    for ( int i = 0; i <= s; i++ )
        tim[i] = true;
    for ( int r = 1; r <= n; r++ ) {
        vector<int> a, b;
        for ( int i = 0; i <= s; i++ ) {
            a.push_back( pos1n[r - 1][i] );
            b.push_back( posn1[r + 1][i] );
        }

        vector<int> pos = multiply( a, b );

        timTemp.reset();
        for ( int i = 0; i <= s; i++ ) {
            if ( pos[i] )
                timTemp[abs( s - v[r] - i - i )] = true;
        }
        tim &= timTemp;
    }

    tim[0] = false;
    cout << tim.count() << "\n";
    for ( int i = 0; i <= s; i++ ) {
        if ( tim[i] )
            cout << i << " ";
    }

    return 0;
}

Compilation message (stderr)

bootfall.cpp: In function 'std::vector<int> multiply(const std::vector<int>&, const std::vector<int>&)':
bootfall.cpp:40:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   40 |     while (n < a.size() + b.size())
      |            ~~^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...