1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <stdio.h> #include <stdlib.h> typedef long long ll; const int nmax = 100000, tmax = 1 << 18, shift = nmax;
int n, m, M = 1, H = 1, a[nmax + 18], last[nmax * 2 + 18], pre[nmax + 18]; ll f[tmax + 18], g[tmax + 18], fd[tmax + 18], gd[tmax + 18], ans[nmax + 18]; int l[nmax + 18], r[nmax + 18], p[nmax + 18];
int cmpor(const void *i, const void *j) {return r[*(int *)i] - r[*(int *)j];} inline int max(int a, int b) {return a > b ? a : b;} inline void update(ll &a, ll b) {if (a < b) a = b;} inline void take(int i) { f[i] = max(f[i << 1], f[i << 1 | 1]), g[i] = max(g[i << 1], g[i << 1 | 1]); }
inline void give(int i, int j) { update(g[i], f[i] + gd[j]), f[i] += fd[j]; update(gd[i], fd[i] + gd[j]), fd[i] += fd[j]; }
void pd(int i) { for (int h = H - 1, j; h; --h) if (fd[j = i >> h] || gd[j]) give(j << 1, j), give(j << 1 | 1, j), fd[j] = gd[j] = 0; }
void add(int l, int r, int x) { for (pd(l += M - 1), pd(r += M + 1); l ^ r ^ 1; take(l >>= 1), take(r >>= 1)) { if (~l & 1) update(g[l ^ 1], f[l ^ 1] += x), update(gd[l ^ 1], fd[l ^ 1] += x); if ( r & 1) update(g[r ^ 1], f[r ^ 1] += x), update(gd[r ^ 1], fd[r ^ 1] += x); } for (int tmp1, tmp2; l >>= 1;) { tmp1 = f[l], tmp2 = g[l]; take(l); if (f[l] == tmp1 && g[l] == tmp2) break; } }
ll getmax(int l, int r) { ll ans = 0; for (pd(l += M - 1), pd(r += M + 1); l ^ r ^ 1; l >>= 1, r >>= 1) { if (~l & 1) update(ans, g[l ^ 1]); if ( r & 1) update(ans, g[r ^ 1]); } return ans; }
int main() { freopen("hungry.in", "r", stdin); freopen("hungry.out", "w", stdout); scanf("%d", &n); while (n >= M - 2) M <<= 1, ++H; for (int i = 1; i <= n; ++i) scanf("%d", a + i), pre[i] = last[a[i] + shift], last[a[i] + shift] = i; scanf("%d", &m); for (int i = 1; i <= m; ++i) scanf("%d%d", l + i, r + i), p[i] = i; qsort(p + 1, m, sizeof(p[0]), cmpor); for (int i = 1, j = 1; i <= n && j <= m; ++i) for (add(pre[i] + 1, i, a[i]); j <= m && r[p[j]] <= i; ++j) ans[p[j]] = getmax(l[p[j]], r[p[j]]); for (int i = 1; i <= m; ++i) printf("%I64d\n", ans[i]); return 0; }
|