写的是正解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;
}