UOJ Logo

NOI.AC

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#164568#2910. candleanti1009566ms72864kbC++113.7kb2022-11-05 08:48:562022-11-05 13:00:22

answer

#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;

const int INF = 0x3f3f3f3f;

typedef pair <long long, int> pli;

pli operator + (const pli &A, const pli &B) {
	return mp(A.fi + B.fi, A.se + B.se);
}

int a[100010];
int POOL[20000000], *CUR = POOL;

void SeqMul(int *f, int n, int *g, int m, int *h) {
	static int tmp[100010];
	int p = 0, q = 0, cur = 0;
	while (p < n || q < m) {
		tmp[cur++] = q == m || p < n && f[p] > g[q] ? f[p++] : g[q++];
	}
	for (int i = 0; i < cur; i++) {
		h[i] = tmp[i];
	}
}

void SeqMax(int *f, int n, int *g, int *h) {
	static int tmp[100010];
	int sf = 0, sg = 0;
	for (int i = 0; i < n; i++) {
		if (f[i] == -INF) sf = -INF;
		else sf += f[i];
		if (g[i] == -INF) sg = -INF;
		else sg += g[i];
		tmp[i] = max(sf, sg);
	}
	for (int i = 0; i < n; i++) {
		h[i] = tmp[i] == -INF ? -INF : tmp[i] - (i ? tmp[i - 1] : 0);
	}
}

pli GetVal(int *f, int n, int *sum, int delta) {
	int pos = upper_bound(f, f + n, delta, greater <int>()) - f;
	return mp((pos ? sum[pos - 1] : 0) - 1ll * pos * delta, pos);
}

namespace SEG {
	struct Node {
		int *f[2][2], *sum[2][2], n;
		void GetMem(int sz) {
			n = sz;
			for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) {
				f[i][j] = CUR, CUR += sz;
				sum[i][j] = CUR, CUR += sz;
			}
		}
		void GetSum() {
			for (int p = 0; p < 2; p++) for (int q = 0; q < 2; q++) {
				for (int i = 0; i < n; i++) {
					if (f[p][q][i] == -INF) break;
					sum[p][q][i] = f[p][q][i] + (i ? sum[p][q][i - 1] : 0);
				}
			}
		}
		void GetTrans(int delta, pli trans[2][2]) {
			for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) {
				trans[i][j] = GetVal(f[i][j], n, sum[i][j], delta);
			}
		}
	}T[1 << 18];
	vector <Node> ans;
	void Build(int now, int l, int r) {
		T[now].GetMem(r - l + 1);
		if (l == r) {
			for (int p = 0; p < 2; p++) for (int q = 0; q < 2; q++) {
				T[now].f[p][q][0] = p && q ? a[l] : -INF;
			}
			T[now].GetSum();
			return ;
		}
		int mid = l + r >> 1;
		Build(now << 1, l, mid), Build(now << 1 | 1, mid + 1, r);
		for (int p = 0; p < 2; p++) for (int q = 0; q < 2; q++) {
			static int tmp[100010];
			SeqMul(T[now << 1].f[p][1], mid - l + 1, T[now << 1 | 1].f[0][q], r - mid, T[now].f[p][q]);
			SeqMul(T[now << 1].f[p][0], mid - l + 1, T[now << 1 | 1].f[1][q], r - mid, tmp);
			SeqMax(tmp, r - l + 1, T[now].f[p][q], T[now].f[p][q]);
		}
		T[now].GetSum();
	}
	void Query(int now, int l, int r, int L, int R) {
		if (now == 1) ans.clear();
		if (l == L && r == R) {
			ans.push_back(T[now]);
			return ;
		}
		int mid = l + r >> 1;
		if (R <= mid) Query(now << 1, l, mid, L, R);
		else if (L > mid) Query(now << 1 | 1, mid + 1, r, L, R);
		else Query(now << 1, l, mid, L, mid), Query(now << 1 | 1, mid + 1, r, mid + 1, R);
	}
	pli Calc(int delta) {
		static pli dp[2]; dp[0] = mp(0, 0), dp[1] = mp(0, 0);
		for (auto it : ans) {
			static pli trans[2][2]; it.GetTrans(delta, trans);
			static pli tmp[2];
			tmp[0] = max(dp[0] + trans[1][0], dp[1] + trans[0][0]);
			tmp[1] = max(dp[0] + trans[1][1], dp[1] + trans[0][1]);
			dp[0] = tmp[0], dp[1] = tmp[1];
		}
		return dp[1];
	}
}

int main() {
	int n, q; scanf("%d%d", &n, &q);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	SEG :: Build(1, 1, n);
	while (q--) {
		int l, r, k; scanf("%d%d%d", &l, &r, &k);
		SEG :: Query(1, 1, n, l, r);
		{
			int l = -k * 10010, r = 10001;
			while (l < r) {
				int mid = (l + 1000000000ll + r + 1000000000ll + 1 >> 1) - 1000000000ll;
				if (SEG :: Calc(mid).se < k) r = mid - 1;
				else l = mid;
			}
			auto it = SEG :: Calc(l);
			printf("%lld\n", it.fi + 1ll * k * l);
		}
	}
	return 0;
}

详细

小提示:点击横条可展开更详细的信息

Subtask #1:

score: 25
Accepted

Test #1:

score: 25
Accepted
time: 291ms
memory: 72844kb

input:

99999 50000
7936 3878 7581 7825 4970 9286 2463 6418 2408 8725 8082 3975 5432 1999 8061 8013 7917 942...

output:

10000
20000
30000
40000
50000
60000
70000
80000
90000
100000
110000
120000
130000
139999
149998
1599...

result:

ok 50000 lines

Test #2:

score: 0
Accepted
time: 306ms
memory: 72824kb

input:

100000 50000
2149 4930 2210 1231 5174 8280 9018 2470 7138 6335 3196 5289 6049 2360 1357 8474 4637 32...

output:

10000
20000
30000
40000
50000
60000
70000
80000
90000
100000
110000
120000
129999
139998
149997
1599...

result:

ok 50000 lines

Subtask #2:

score: 25
Accepted

Test #3:

score: 25
Accepted
time: 3393ms
memory: 72844kb

input:

100000 100000
7395 1842 8275 3045 7119 38 6161 5602 7464 1962 5542 7883 919 7718 7444 6052 2725 8461...

output:

10000
49996
19999
49995
29998
40000
50000
49999
20000
29997
99877
10000
99921
79994
99989
19997
1000...

result:

ok 100000 lines

Test #4:

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

input:

1 10
10000
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1

output:

10000
10000
10000
10000
10000
10000
10000
10000
10000
10000

result:

ok 10 lines

Subtask #3:

score: 25
Accepted

Test #5:

score: 25
Accepted
time: 585ms
memory: 72848kb

input:

100000 10000
295 2236 8929 8771 6320 2631 9323 6827 2590 5004 2832 3613 6382 1813 9071 9431 5194 986...

output:

236223832
29453306
157750501
256791188
140507773
145099378
88099683
69069259
48422834
158572737
9337...

result:

ok 10000 lines

Test #6:

score: 0
Accepted
time: 410ms
memory: 72864kb

input:

99999 10000
9999 1 9996 1 9997 1 9996 1 9999 1 9998 1 9998 1 9998 1 9996 1 9999 1 9999 1 10000 1 999...

output:

6670000
10738831
100470718
42107528
17288723
305249166
355440959
11099910
224550876
13208891
7126682...

result:

ok 10000 lines

Subtask #4:

score: 25
Accepted

Test #7:

score: 25
Accepted
time: 4581ms
memory: 72848kb

input:

100000 100000
2729 8888 6338 1816 6413 5065 9682 5273 5624 7938 3312 9510 8404 7373 8832 723 5049 25...

output:

6437503
177675737
154195231
125078340
23156704
6678548
58492583
82641011
141266402
6120039
24211416
...

result:

ok 100000 lines