HELP! 90pts WA on 3,4
查看原帖
HELP! 90pts WA on 3,4
47425
clarkwang楼主2023/10/20 12:17

写的是正解ST表维护的暴力(?

很玄学的挂了最小的两个点

求查错

#include <iostream>
#include <cstdio>

using namespace std;

inline long long read() {
	static long long res;
	static char ch;
	res = 0;
	do {
		ch = getchar();
	} while(!isdigit(ch));
	do {
		res = (res << 3) + (res << 1) + (ch ^ '0');
		ch = getchar();
	} while(isdigit(ch));
	return res;
}

inline void write(long long x, char ed = '\n') {
    printf("%lld%c", x, ed);
    return;
	if(x < 0) {
		putchar('-');
		x = -x;
	}
	static char st[20];
	static short top;
	top = 0;
	while(x) {
		st[++top] = (x % 10) ^ '0';
		x /= 10;
	}
	if(!top) putchar('0');
	else do {
		putchar(st[top]);
	} while(--top);
	putchar(ed);
}

int n, m, q;
long long a[500001];
long long ST[500001][21];
long long b[500001];
long long c[500001];
long long emp[500001];
int p[500001];

inline long long getMin(int l, int r) {
	if(r == n) return ST[l][20];
	long long res = ST[r][0];
	for(int i = 20, d = (1 << 20);i >= 0;i--, d >>= 1) {
		if(l + d <= r) {
			res = min(res, ST[l][i]);
			l += d;
		}
	    if(l == r) return res;
	}
	return res;
}

//1,l:eaten by A, recover by C
//l+1,r:empty,no thing's here
//r+1,n:cover by B
inline long long getVal(int l, int r, long long &cs, long long &bs) {
	return getMin(l, r) + cs - bs;
}

int main() {
//	freopen("./reserve/reserve8.in", "r", stdin);
//	freopen("A.out", "w", stdout);
	n = read();
	for(int i = 1;i <= n;i++) ST[i][0] = a[i] = read();
	for(int i = 1;i <= n;i++) b[i] = read();
	for(int i = 1;i <= n;i++) c[i] = read();
	emp[n] = b[n];
	emp[0] = min(a[n], a[n - 1] + emp[n]);
	for(int i = n - 1;i >= 1;i--) {
		emp[i] = emp[i + 1] + b[i];
		emp[0] = min(emp[0], a[i - 1] + emp[i]);
		ST[i][0] += emp[i + 1];
	}
	for(int t = 1, d = 1;t <= 20;t++, d <<= 1) {
		for(int i = 1;i + d <= n;i++) ST[i][t] = min(ST[i][t - 1], ST[i + d][t - 1]);
		for(int i = n;i > n - d && i > 0;i--) ST[i][t] = ST[i][t - 1];
	}
	q = read();
	while(q--) {
		m = read();
		long long bs = 0, cs = 0;
		for(int i = 1;i <= m;i++) {
			p[i] = read();
			bs += b[p[i]];
		}
		if(m == 0) {
			write(emp[0]);
			continue;
		}
		long long ans = (1LL << 60);
		if(p[1] == 1) ans = min(ans, emp[1] - bs);
		else ans = min(ans, getVal(1, p[1] - 1, cs, bs));
		for(int i = 1;i < m;i++) {
			cs += c[p[i]];
			bs -= b[p[i]];
			ans = min(ans, getVal(p[i], p[i + 1] - 1, cs, bs));
		}
		cs += c[p[m]];
		bs -= b[p[m]];
		ans = min(ans, getVal(p[m], n, cs, bs));
		write(ans);
	}
	return 0;
}
2023/10/20 12:17
加载中...