Submission #678402

#TimeUsernameProblemLanguageResultExecution timeMemory
678402Ahmed57Bootfall (IZhO17_bootfall)C++17
100 / 100
514 ms6136 KiB
/* IZhO 17-bootfall Do knapsack for the initial n items. We will store count[i] = how many subsets have sum i, mod some big prime. When we want to remove 1 item, we have to reverse the knapsack and then revert back to the initial state. At the end, we need to check how many differences appear in all of the n removals, and this can be counted with a frequency array. */ #include<bits/stdc++.h> #define god dimasi5eks #pragma GCC optimize("O3") #define fi first #define se second #define pb push_back #define pf push_front #define mod 1000000007 #define dancila 3.14159265359 #define eps 1e-9 using namespace std; typedef long long ll; int add(int a, int b) { ll x = a+b; if(x >= mod) x -= mod; if(x < 0) x += mod; return x; } ll mul(ll a, ll b) { return (a*b) % mod; } ll pw(ll a, ll b) { ll ans = 1; while(b) { if(b & 1) ans = (ans * a) % mod; a = (a * a) % mod; b >>= 1; } return ans; } mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); long long rand_seed() { long long a = rng(); return a; } int n; int v[502]; int frq[1000002]; bool dp[250002]; int ct[250002], ct2[250002]; int fi[250002]; int lst[250002]; bool canruk(int lack) { int sm = 0; for(int i = 1; i <= n; ++i) if(i != lack) sm += v[i]; if(lack == 0) { int mxval = 0; dp[0] = 1; ct[0] = 1; for(int i = 1; i <= n; ++i) { for(int j = mxval; j >= 0; --j) if(dp[j]) { ct[j + v[i]] = add(ct[j + v[i]], ct[j]); if(!fi[j + v[i]]) fi[j + v[i]] = i; lst[j + v[i]] = i; dp[j + v[i]] = 1; } mxval += v[i]; } if(mxval % 2 == 0 && dp[mxval / 2]) return 1; return 0; } else { for(int j = 0; j <= sm + v[lack]; ++j) ct2[j] = ct[j]; for(int j = v[lack]; j <= sm + v[lack]; ++j) ct[j] = add(ct[j], -ct[j - v[lack]]); for(int i = 0; i <= sm/2; ++i) if(ct[i]) frq[sm - 2 * i]++; for(int j = 0; j <= sm + v[lack]; ++j) ct[j] = ct2[j]; return 1; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n; for(int i = 1; i <= n; ++i) cin >> v[i]; sort(v+1, v+n+1); if(!canruk(0)) { cout << 0; return 0; } for(int i = 1; i <= n; ++i) canruk(i); int nrok = 0; for(int i = 0; i <= 1000000; ++i) if(frq[i] == n) ++nrok; cout << nrok << '\n'; for(int i = 0; i <= 1000000; ++i) if(frq[i] == n) cout << i << " "; return 0; }
#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...