## 51nod1463 找朋友

[传送门]

$A$: 1 2 3 4
$B$: 3 2 1 4
$i = 1$：0 0 0 5
$i = 2$：3 0 0 0
$i = 3$：0 5 0 7
$i = 4$：0 0 0 0

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5 + 7;

struct Seg {
#define lp p << 1
#define rp p << 1 | 1
ll tree[N << 4];
inline void pushup(int p) {
tree[p] = max(tree[lp], tree[rp]);
}
void update(int p, int l, int r, int pos, ll val) {
if (l == r) {
tree[p] = max(tree[p], val);
return;
}
int mid = l + r >> 1;
if (pos <= mid) update(lp, l, mid, pos, val);
else update(rp, mid + 1, r, pos, val);
pushup(p);
}
ll query(int p, int l, int r, int x, int y) {
if (x <= l && y >= r) return tree[p];
int mid = l + r >> 1;
ll ans = 0;
if (x <= mid) ans = max(ans, query(lp, l, mid, x, y));
if (y > mid) ans = max(ans, query(rp, mid + 1, r, x, y));
return ans;
}
} seg;

struct Query {
int l, r, id;
inline bool operator < (const Query &rhs) const {
return r < rhs.r;
}
} query[N];

ll a[N], ans[N];
int b[N], k[N], pos[N];

int main() {
int n, q, m;
scanf("%d%d%d", &n, &q, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for (int i = 1; i <= n; i++)
scanf("%d", &b[i]), pos[b[i]] = i;
for (int i = 1; i <= m; i++)
scanf("%d", &k[i]);
for (int i = 1; i <= q; i++)
scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i;
sort(query + 1, query + 1 + q);
int now = 0;
for (int i = 1; i <= q; i++) {
while (now < query[i].r) {
now++;
ll mx = 0;
for (int j = 1; j <= m; j++) {
int temp = b[now] - k[j];
if (temp > 0 && temp <= n && pos[temp] < now) seg.update(1, 1, n, pos[temp], a[now] + a[pos[temp]]);
temp = b[now] + k[j];
if (temp <= n && temp > 0 && pos[temp] < now) seg.update(1, 1, n, pos[temp], a[now] + a[pos[temp]]);
}
}
ans[query[i].id] = seg.query(1, 1, n, query[i].l, query[i].r);
}
for (int i = 1; i <= q; i++)
printf("%lld\n", ans[i]);
return 0;
}
View Code