QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#285851#4414. Divide the SweetsAtomAlpacaWA 5814ms62032kbC++142.9kb2023-12-16 23:34:222023-12-16 23:34:23

Judging History

你现在查看的是最新测评结果

  • [2023-12-16 23:34:23]
  • 评测
  • 测评结果:WA
  • 用时:5814ms
  • 内存:62032kb
  • [2023-12-16 23:34:22]
  • 提交

answer

#include <bits/stdc++.h>

typedef long long ll;

const int MOD = 998244353;
const ll MAX = 1 << 21;
const ll INF = 1e16;

int n, m, L, R, cnt, T;
struct P { ll k, b; } p[MAX];
ll w[MAX], sum[MAX], mul[MAX], pct[MAX], lst[MAX], now[MAX], st[MAX], ed[MAX], A1[MAX], ans[29];

inline int lbt(int x) { return x & -x; }
bool cmp(ll x, ll y) { return sum[x] < sum[y]; }

void ins(P x)
{
	while (L <= R - 1 and (p[R - 1].b - p[R].b) * (x.k - p[R].k) <= (p[R].b - x.b) * (p[R].k - p[R - 1].k)) { --R; }
	p[++R] = x;
}

void merge(ll l1, ll r1, ll l2, ll r2)
{
	L = R + 1;
	for (; l1 <= r1 and l2 <= r2; )
	{
		if (p[l1].k != p[l2].k) { ins(p[l1].k < p[l2].k ? p[l1++] : p[l2++]); }
		else { ins(p[l1].b < p[l2].b ? p[l1] : p[l2]); ++l1; ++l2; }
	}
	while (l1 <= r1) { ins(p[l1++]); }
	while (l2 <= r2) { ins(p[l2++]); }
}

void solve()
{
	scanf("%d%d", &n, &m); ll fnt = n >> 1, bck = n - fnt;
	for (int i = 1; i <= n; ++i) { scanf("%lld", &w[i - 1]); }
	for (ll i = 1; i <= (1ll << n) - 1; ++i)
	{
		ll lg = __builtin_ctz(lbt(i));
		pct[i] = pct[i ^ lbt(i)] + 1;
		sum[i] = sum[i ^ lbt(i)] + w[lg];
		mul[i] = mul[i ^ lbt(i)] + w[lg] * w[lg];
	}
	now[0] = INF;
	for (ll i = 1; i <= (1ll << n) - 1; ++i)
	{
		now[i] = sum[i] * sum[i];
		ans[1] = (ans[1] + now[i]) % MOD;
	}
	for (int i = 2; i <= m; ++i)
	{
		for (ll j = 1; j <= (1ll << n) - 1; ++j)
		{
			lst[j] = now[j];
			now[j] = (pct[j] <= i ? mul[j] : INF);
		}
		for (ll A0 = 0; A0 <= (1ll << fnt) - 1; ++A0)
		{
			cnt = 0;
			for (ll j = A0; ; j = (j + 1) | A0)
			{
				A1[++cnt] = j << bck;
				if (j == (1 << fnt) - 1) { break; }
			}
			std::sort(A1 + 1, A1 + cnt + 1, cmp);
			R = 0;
			for (ll B0 = 0; B0 <= (1 << bck) - 1; ++B0)
			{
				st[B0] = R + 1;
				ll C = A0 << bck | B0;
				if (pct[C] >= i - 1) { p[++R] = {sum[C], lst[C] + sum[C] * sum[C]}; }
				ed[B0] = R;
			}
			for (int j = 1; j <= bck; ++j)
			{
				for (ll B0 = 0; B0 <= (1 << bck) - 1; ++B0)
				{
					if ((B0 >> (j - 1) & 1) == 0) { continue; }
					int tmp = R + 1;
					merge(st[B0], ed[B0], st[B0 ^ (1 << (j - 1))], ed[B0 ^ (1 << (j - 1))]);
					st[B0] = tmp;
					ed[B0] = R;
				}
			}
			for (ll B1 = 0; B1 <= (1 << bck) - 1; ++B1)
			{
				ll l = st[B1], r = ed[B1];
				if (l > r) { continue; }
//				printf("%lld ", B1);
				for (int j = 1; j <= cnt; ++j)
				{
					ll S = A1[j] | B1;
					if (pct[S] <= i) { continue; }
//					printf("%lld ", S);
					ll x = -2ll * sum[S];
					while (l < r and p[l].k * x + p[l].b > p[l + 1].k * x + p[l + 1].b) { ++l; }
					now[S] = std::min(now[S], p[l].k * x + p[l].b);
				}
			}
		}
		for (ll j = 1; j <= (1ll << n) - 1; ++j)
		{
			if (pct[j] > i) { now[j] += sum[j] * sum[j]; }
			ans[i] = (ans[i] + now[j]) % MOD;
		}
	}
	for (int i = 1; i <= m; ++i) { printf("%lld\n", ans[i]); }
}

int main() { scanf("%d", &T); while (T--) { solve(); } }

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 5814ms
memory: 62032kb

input:

50
1 1
41157
2 2
42567 45459
3 3
18704 43514 6548
4 4
17662 19185 22570 28320
5 5
12535 20205 16505 10400 35580
6 6
35939 41496 10203 32740 30192 13030
7 7
30302 23454 8704 15004 27743 15952 25399
8 8
12327 33605 17303 14647 34972 28109 40172 49588
9 9
32280 30113 13060 40035 2051 45364 40615 40351 ...

output:

695654296
343768906
769229869
398241708
176470387
160537287
223587693
29883166
797820731
957836857
619038323
720498875
627922817
671842949
451522445
94821841
205957370
339612829
564969952
682158888
962990616
861519987
263396513
132731321
960381347
84279240
671730619
445794724
50578596
514219878
9060...

result:

wrong answer 2nd lines differ - expected: '646358963', found: '343768906'