QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#665406#7417. Honorable Mentionuser10086WA 2122ms52084kbC++235.9kb2024-10-22 12:23:162024-10-22 12:23:17

Judging History

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

  • [2024-10-22 12:23:17]
  • 评测
  • 测评结果:WA
  • 用时:2122ms
  • 内存:52084kb
  • [2024-10-22 12:23:16]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(x) (x).begin(), (x).end()

#define printf

const int N = 3.5e4 + 10, inf = 1e10;

void chkmax(int &x, int y)
{
	if (y > x) x = y;
}

int cnt;

namespace tree
{
	int n, len[N << 2];
	vector<int> d[N << 2][2][2], sum[N << 2][2][2]; // sum[0] = f(1), f(0) = 0
	int v0[N << 2][2][2];
	
	void pushup(int i)
	{
		for (int c00 : {0, 1}) for (int c11 : {0, 1})
			{
				v0[i][c00][c11] = LLONG_MIN;
				d[i][c00][c11].resize(len[i], -inf);
				sum[i][c00][c11].resize(len[i], -inf);
				for (int c01 : {0, 1}) for (int c10 : {0, 1})
				{
					vector<int> tmp(d[i << 1][c00][c01].size() + d[i << 1 | 1][c10][c11].size());
					merge(all(d[i << 1][c00][c01]), all(d[i << 1 | 1][c10][c11]), tmp.begin(), greater<int>());
					int tmpv0 = v0[i << 1][c00][c01] + v0[i << 1 | 1][c10][c11];
					chkmax(v0[i][c00][c11], tmpv0);
					int cur = tmpv0;
					for (int x = 0; x < tmp.size(); x++) cur += tmp[x], chkmax(sum[i][c00][c11][x], cur);
					if (c01 && c10)
					{
					 // pop front
						cur = tmpv0 + tmp[0];
						for (int x = 0; x + 1 < tmp.size(); x++) cur += tmp[x + 1], chkmax(sum[i][c00][c11][x], cur);
//					if (i == 4 && c00 == 1 && c11 == 1) 
//					{
//						cout << tmpv0 << '/';
//						for (int x : tmp) cout << x << ' '; cout << endl;
//						assert(tmpv0 <= -2 * inf), assert(sum[i][c00][c11][0] < 0);
//					}
					}
				}
				for (int x = (int)sum[i][c00][c11].size() - 1; x >= 1; x--) d[i][c00][c11][x] = sum[i][c00][c11][x] - sum[i][c00][c11][x - 1];
				d[i][c00][c11].front() = sum[i][c00][c11].front() - v0[i][c00][c11];
				for (int x = 0; x < d[i][c00][c11].size(); x++)
				{
					if (d[i][c00][c11][x] < -5e9)
					{
						for (int j = x; j < d[i][c00][c11].size(); j++) d[i][c00][c11][j] = -inf;
						break;
					}
				}
			}
//		for (int x = 0; x <= len[i]; x++) 
//			for (int c0 : {0, 1}) for (int c1 : {0, 1})
//				f[i][x][c0][c1] = -inf;
//		for (int x = 0; x <= len[i << 1]; x++)
//			for (int y = 0; y <= len[i << 1 | 1]; y++)
//				for (int c00 : {0, 1}) for (int c01 : {0, 1}) for (int c10 : {0, 1}) for (int c11 : {0, 1})
//				{
//					if (f[i << 1][x][c00][c01] <= -inf || f[i << 1 | 1][y][c10][c11] <= -inf) continue;
//					chkmax(f[i][x + y - (c01 && c10)][c00][c11], f[i << 1][x][c00][c01] + f[i << 1 | 1][y][c10][c11]);
//				}
	}
	
	void build(int i, int *a, int li, int ri)
	{
		len[i] = ri - li + 1;
		if (li == ri)
		{
			d[i][0][0].resize(1, -inf), d[i][1][1].resize(1, a[li] + inf), d[i][0][1].resize(1, 0), d[i][1][0].resize(1, 0);
			v0[i][0][0] = 0, v0[i][1][0] = v0[i][0][1] = v0[i][1][1] = -inf;
			for (int c0 : {0, 1})
				for (int c1 : {0, 1}) sum[i][c0][c1] = d[i][c0][c1], sum[i][c0][c1][0] += v0[i][c0][c1];
			return;
		}
		int mid = (li + ri) >> 1;
		build(i << 1, a, li, mid), build(i << 1 | 1, a, mid + 1, ri);
		pushup(i);
	}
	
	void init(int *a, int sz)
	{
		n = sz;
		build(1, a, 1, n);
	}

	void print(int i = 1, int li = 1, int ri = n)
	{
		printf("node %lld : [%lld, %lld]\n", i, li, ri);
		for (int c0 : {0, 1})
			for (int c1 : {0, 1})
			{
				printf("v0(%lld, %lld, %lld) = %lld\n", i, c0, c1, v0[i][c0][c1]);
				printf("sum(%lld, %lld, %lld): ", i, c0, c1);
				for (int x : sum[i][c0][c1]) printf("%lld ", x); printf("\n");
				printf("d(%lld, %lld, %lld): ", i, c0, c1);
				for (int x : d[i][c0][c1]) printf("%lld ", x); printf("\n");
			}
		if (li == ri) return;
		int mid = (li + ri) >> 1;
		print(i << 1, li, mid), print(i << 1 | 1, mid + 1, ri);
	}
	
	typedef array<array<array<int, 2>, 2>, 2> info; // info[c0][c1] = {x, f(x) - px}
	
	info null = {};

	info merge(info x, info y, int p)
	{
		if (x == null) swap(x, y);
		if (y == null) return x;
		
		info res;
		for (int c0 : {0, 1}) for (int c1 : {0, 1}) 
			res[c0][c1] = {0, -inf};
		for (int c00 : {0, 1}) for (int c11 : {0, 1})
		{
			for (int c01 : {0, 1}) for (int c10 : {0, 1})
			{
				int val = x[c00][c01][1] + y[c10][c11][1];
				if (val > res[c00][c11][1]) res[c00][c11] = {x[c00][c01][0] + y[c10][c11][0] - (c01 && c10), val + p * (c01 && c10)};
			}
		}
		return res;
	}	
	
	info getinfo(int l, int r, int p, int i = 1, int li = 1, int ri = n)
	{
		printf("getinfo(%lld, %lld, %lld, %lld, %lld, %lld)\n", l, r, p, i, li, ri);
		if (l <= li && ri <= r)
		{
			info res;
			for (int c0 : {0, 1}) for (int c1 : {0, 1})
			{
				int id = lower_bound(all(d[i][c0][c1]), p, greater<int>()) - d[i][c0][c1].begin() - 1;
				assert(-1 <= id && id < (int)sum[i][c0][c1].size());
				if (id < 0) res[c0][c1] = {0, v0[i][c0][c1]};
				else res[c0][c1] = {id + 1, sum[i][c0][c1][id]};
				res[c0][c1][1] -= res[c0][c1][0] * p;
			}
			return res;
		}
		int mid = (li + ri) >> 1;
		info cur = null;
		if (l <= mid) cur = getinfo(l, r, p, i << 1, li, mid);
		if (r > mid) cur = merge(cur, getinfo(l, r, p, i << 1 | 1, mid + 1, ri), p);
		return cur;
	}
}

int n, q, a[N];

//int F(int q, int n)
//{
//	if (q == 0) return 1;
//	if (q == 1) return __lg(n) + 1;
//	if (n == 1) return q;
//	return F(q / 2, n / 2) + F((q + 1) / 2, (n + 1) / 2) + min(q * (__lg(n) + 1) * (__lg(n) + 1), 4 * n);
//}

const int V = 3.5e4 + 10;

signed main()
{
	cin >> n >> q;
	for (int i = 1; i <= n; i++) cin >> a[i];
	tree::init(a, n);
	tree::print();
	while (q--)
	{
		int l, r, k; cin >> l >> r >> k;
		int pl = -2 * inf, pr = 2 * inf;
		while (pl < pr)
		{
			int mid = (pl + pr) >> 1;
			auto res = tree::getinfo(l, r, mid);
			int val = -inf, x = 0;
			for (int c0 : {0, 1}) for (int c1 : {0, 1})
				if (res[c0][c1][1] > val) val = res[c0][c1][1], x = res[c0][c1][0];
			printf("x = %lld, val = %lld, pl = %lld, pr = %lld, mid = %lld\n", x, val, pl, pr, mid);
			if (x > k) pl = mid + 1;
			else pr = mid;
		}
		auto res = tree::getinfo(l, r, pl);
		int val = -inf;
		for (int c0 : {0, 1}) for (int c1 : {0, 1})
			chkmax(val, res[c0][c1][1]);
		cout << val + k * pl << endl;
	}
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 5684kb

input:

5 5
-1 2 -3 4 -5
1 5 1
1 5 2
1 5 3
1 5 4
1 5 5

output:

4
6
5
2
-3

result:

ok 5 number(s): "4 6 5 2 -3"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3712kb

input:

5 1
7 7 7 7 7
1 5 1

output:

35

result:

ok 1 number(s): "35"

Test #3:

score: -100
Wrong Answer
time: 2122ms
memory: 52084kb

input:

25000 25000
-11889 -16468 18402 -13238 14125 12120 -3295 -12106 20152 7478 8575 9968 -13946 -13408 23715 -14670 -21837 12589 7029 20609 2868 12728 -6942 982 5884 -7561 -2058 -7892 7806 16344 14645 13904 7355 9860 15446 -539 24072 21969 19028 -24939 -21911 -11836 21045 -4727 -3882 2138 18513 -4796 -1...

output:

10341941
44514177
6440759
77971944
99594350
107722534
15428815
17295793
62015893
10651564
41149301
22801910
9398221
8872420
39274544
72246054
5099132
41931412
52700848
37955687
37027805
4510644
16263093
16809596
107985169
28135446
46572409
768203
102809758
27823424
50330656
16334941
2790814
21112728...

result:

wrong answer 3rd numbers differ - expected: '6687268', found: '6440759'