Submission #592125

#TimeUsernameProblemLanguageResultExecution timeMemory
592125tutisUplifting Excursion (BOI22_vault)C++17
45 / 100
5056 ms85332 KiB
/*input
2 5
2 3 1 1 4

*/

#pragma GCC optimize ("O3")
#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T,  null_type,  less<T>,  rb_tree_tag,  tree_order_statistics_node_update>;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
mt19937_64 rng(0);
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int M;
	ll L;
	cin >> M >> L;
	ll A_[2 * M + 1];
	ll* A = A_ + M;
	for (int i = -M; i <= M; i++)
		cin >> A[i];
	ll pl = 0;
	pl += A[0];
	A[0] = 0;
	L = -L;
	ll cnt = 0;
	for (int l = -M; l <= M; l++)
	{
		L += l * A[l];
		cnt += A[l];
	}
	cc_hash_table<ll, ll>D;
	D[0] = 0;
	ll del = M;
	cc_hash_table<ll, int>X[M + 1];
	X[0][0] = 0;
	int mxe = 50;
	for (int v = 1; v <= M; v++)
	{
		for (pair<ll, int>a : X[v - 1])
		{
			int mxe1 = mxe - a.second;
			for (int l : {v, -v})
			{
				for (int i = 0; i <= mxe1 && i <= A[l]; i++)
				{
					ll val = a.first + i * l;
					int ej = a.second + i;
					auto it = X[v].find(val);
					if (it == X[v].end())
						X[v][val] = ej;
					else
						it->second = min(it->second, ej);
				}
			}
		}
	}
	if (X[M].find(L) != X[M].end())
	{
		cout << pl + cnt - X[M][L] << "\n";
		return 0;
	}
	ll infi = 5e18;
	ll best = infi;
	A[0] = 1;
	for (int v = M; v >= 1; v--)
		for (int l : {v, -v})
		{
			if (l == 0)
				continue;
			cc_hash_table<ll, ll>D_;
			for (pair<ll, ll>v : D)
			{
				if (v.second >= best)
					continue;
				ll k = (L - v.first) / l;
				k = max(k, 0ll);
				k = min(k, A[l]);
				ll lo = max(0ll, k - del);
				ll hi = min(k + del, A[l]);
				if (abs(L - (v.first + k * l)) < abs(l) && A[L - (v.first + k * l)] > 0)
				{
					int d = 1;
					if (L - (v.first + k * l) == 0)
						d = 0;
					ll c_ = v.second + k + d;
					best = min(best, c_);
				}
				else
				{
					for (ll c = lo; c <= hi; c++)
					{
						ll v_ = v.first + l * c;
						ll c_ = v.second + c;
						if (c_ >= best)
							continue;
						auto it1 = X[abs(l) - 1].find(L - v_);
						if (it1 != X[abs(l) - 1].end())
						{
							best = min(best, c_ + it1->second);
						}
						else {
							auto it = D_.find(v_);
							if (it == D_.end())
								D_[v_] = c_;
							else
								it->second = min(it->second, c_);
						}
					}
				}
			}
			D = D_;
		}
	if (best < infi)
		cout << pl + cnt - best << "\n";
	else
		cout << "impossible\n";
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...