[POI2015]KIN[線段樹]
阿新 • • 發佈:2019-04-11
mdf cst string int ons pac 線段 scanf lse
很套路的維護最大和子段
#include <cmath> #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <complex> #include <ctime> #include <vector> #define mp(x, y) make_pair(x, y) using namespace std; const int N = 1e6 + 5; int n, m, L; long long ans, res; int a[N], b[N]; int pre[N], rec[N]; bool vis[N]; struct Seg{ long long w[N << 2], ls[N << 2], rs[N << 2], sum[N << 2]; void update(int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; w[rt] = rs[rt << 1] + ls[rt << 1 | 1]; ls[rt] = max(ls[rt << 1], sum[rt << 1] + ls[rt << 1 | 1]); rs[rt] = max(rs[rt << 1 | 1], sum[rt << 1 | 1] + rs[rt << 1]); // printf("%d %lld %lld %lld\n", rt, w[rt], ls[rt], rs[rt]); } void mdf(int rt, int l, int r, int x, int d){ if(l == r){sum[rt] = d, ls[rt] = rs[rt] = w[rt] = max(0, d); return;} int mid = l + ((r - l) >> 1); if(x <= mid) mdf(rt << 1, l, mid, x, d); else mdf(rt << 1 | 1, mid + 1, r, x, d); update(rt); } }seg; int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), pre[i] = rec[a[i]], rec[a[i]] = i; for(int i = 1; i <= m; ++i) scanf("%d", &b[i]); for(int i = 1; i <= n; ++i){ seg.mdf(1, 1, n, i, b[a[i]]); if(pre[i]) seg.mdf(1, 1, n, pre[i], -b[a[i]]); if(pre[pre[i]]) seg.mdf(1, 1, n, pre[pre[i]], 0); ans = max(ans, seg.w[1]); } printf("%lld\n", ans); return 0; }
[POI2015]KIN[線段樹]