Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- #define int ll
- const ll MAXN = 3E5 + 5;
- const ll BAD = 3E5;
- const ll INF = 1E18 + 18;
- ll n, m;
- ll d[MAXN],
- h[MAXN];
- ll sumd[MAXN],
- first[MAXN],
- second[MAXN];
- struct Node
- {
- int max_a_ind,
- max_b_ind,
- ans_a_ind,
- ans_b_ind;
- Node():
- max_a_ind(BAD),
- max_b_ind(BAD),
- ans_a_ind(BAD),
- ans_b_ind(BAD)
- {}
- Node(int i):
- max_a_ind(i),
- max_b_ind(i),
- ans_a_ind(BAD),
- ans_b_ind(BAD)
- {}
- };
- ll func(const Node & x)
- {
- return first[x.ans_a_ind] + second[x.ans_b_ind];
- }
- Node t[4 * MAXN];
- Node merge(const Node & l, const Node & r)
- {
- Node result;
- result.max_a_ind = first[l.max_a_ind] > first[r.max_a_ind] ? l.max_a_ind : r.max_a_ind;
- result.max_b_ind = second[l.max_b_ind] > second[r.max_b_ind] ? l.max_b_ind : r.max_b_ind;
- ll l_res = func(l);
- ll m_res = first[l.max_a_ind] + second[r.max_b_ind];
- ll r_res = func(r);
- ll mx = max(l_res, max(m_res, r_res));
- if (l_res == mx)
- {
- result.ans_a_ind = l.ans_a_ind;
- result.ans_b_ind = l.ans_b_ind;
- }
- else if (m_res == mx)
- {
- result.ans_a_ind = l.max_a_ind;
- result.ans_b_ind = r.max_b_ind;
- }
- else
- {
- result.ans_a_ind = r.ans_a_ind;
- result.ans_b_ind = r.ans_b_ind;
- }
- return result;
- }
- #define ls (2 * v + 1)
- #define rs (2 * v + 2)
- void build(int v, int vl, int vr)
- {
- if (vr - vl < 1)
- {
- return;
- }
- if (vr - vl == 1)
- {
- t[v] = Node(vl);
- }
- else
- {
- int vm = (vl + vr) / 2;
- build(ls, vl, vm);
- build(rs, vm, vr);
- t[v] = merge(t[ls], t[rs]);
- }
- }
- Node q(int v, int vl, int vr, int ql, int qr) // [l, r)
- {
- if (qr <= vl || vr <= ql)
- {
- return Node();
- }
- if (ql <= vl && vr <= qr)
- {
- return t[v];
- }
- int vm = (vl + vr) / 2;
- return merge(q(ls, vl, vm, ql, qr), q(rs, vm, vr, ql, qr));
- }
- Node query(int l, int r) // [l, r]
- {
- return q(0, 0, MAXN, l, r + 1);
- }
- void solve(int a, int b)
- {
- if (a > b)
- {
- b += n;
- }
- auto xx = query(b + 1, a + n - 1);
- cout << func(xx) << '\n';
- }
- int32_t main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- first[BAD] = -INF;
- second[BAD] = -INF;
- cin >> n >> m;
- for (int i = 0; i < n; ++i)
- {
- cin >> d[i];
- }
- for (int i = 0; i < n; ++i)
- {
- cin >> h[i];
- }
- sumd[0] = 0;
- for (int i = 0; i < n; ++i)
- {
- d[n + i] = d[i];
- h[i + n] = h[i];
- }
- for (int i = 0; i < 2 * n; ++i)
- {
- sumd[i + 1] = sumd[i] + d[i];
- }
- for (int i = 0; i < 2 * n; ++i)
- {
- first[i] = 2 * h[i] - sumd[i];
- second[i] = 2 * h[i] + sumd[i];
- }
- build(0, 0, MAXN);
- while (m--)
- {
- int a, b;
- cin >> a >> b;
- solve(a - 1, b - 1);
- }
- /*while (m--)
- {
- int l, r;
- cin >> l >> r;
- --l; --r;
- Node ans = query(l, r);
- cout << "Max first on [l; r]: " << ans.max_a_ind + 1 << ' ' << first[ans.max_a_ind] << endl;
- cout << "Max second on [l; r]: " << ans.max_b_ind + 1 << ' ' << second[ans.max_b_ind] << endl;
- cout << "Max answer: " << ans.ans_a_ind + 1 << ' ' << ans.ans_b_ind + 1 << ' ' << func(ans) << endl;
- }*/
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement