试题链接
题目描述
题意:
有两个序列,
操作1是将a序列的第x位改成y
操作2是将b序列的第x位改成y
操作3是找到一个cx,满足递推式c0=0,ci = max(ci-1+bi,ai)
题解:
官方题解
说实话我没大看懂。。。
题是我同学做的,他的思路是通过这个递推式可以推导出一个式子
然后用两个线段树来维护,一个用来维护ai-si的差值,一个用来维护b的前缀和
u1s1,码风不错,直接学习
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//simplify long long
typedef unsigned long long ull;
#define inf 2147483647
#define pi 3.14159265358979
#define rep(i, l, r) for(int i = l; i <= r; i ++)
#define lop(i, r, l) for(int i = r; i >= l; i --)
#define step(i, l, r, __step) for(int i = l; i <= r; i += __step)
#define revp(i, r, l, __step) for(int i = r; i >= l; i -= __step)
#define regsiter reg
#define regsiter int RI
#define regsiter long long RL
inline ll read()//fast read
{ll ret = 0, sgn = 1;char chr = getchar();while(chr < '0' || chr > '9'){if(chr == '-') sgn = -1; chr = getchar();}while(chr >= '0' && chr <= '9'){ret = ret * 10 + chr - '0'; chr = getchar();}return ret * sgn;
}
const int N = 2e5 + 5;
int n, m;
struct seg{int l, r;ll sum, maxw, add;
}tr[N << 2][2];
#define ls p << 1
#define rs p << 1 | 1
ll A[N], B[N], S[N], E[N];
inline void update(int p, int t)
{tr[p][t].sum = tr[ls][t].sum + tr[rs][t].sum;tr[p][t].maxw = max(tr[ls][t].maxw, tr[rs][t].maxw);
}
void build(int p, int l, int r, int t)
{tr[p][t].l = l;tr[p][t].r = r;tr[p][t].add = 0;if(l == r){if(!t){tr[p][t].sum = S[l];tr[p][t].maxw = S[l];}else{tr[p][t].sum = E[l];tr[p][t].maxw = E[l];}return;}int mid = l + r >> 1;build(ls, l, mid, t);build(rs, mid + 1, r, t);update(p, t);
}
void pushdown(int p, int t)
{if(tr[p][t].add){ll v = tr[p][t].add;tr[p][t].add = 0;tr[ls][t].add += v;tr[ls][t].sum += v * (tr[ls][t].r - tr[ls][t].l + 1);tr[ls][t].maxw += v;tr[rs][t].add += v;tr[rs][t].sum += v * (tr[rs][t].r - tr[rs][t].l + 1);tr[rs][t].maxw += v;}
}
void modify_add(int p, int l, int r, ll v, int t)
{if(l <= tr[p][t].l && r >= tr[p][t].r){tr[p][t].add += v;tr[p][t].sum += v * (tr[p][t].r - tr[p][t].l + 1);tr[p][t].maxw += v;return;}pushdown(p, t);int mid = tr[p][t].l + tr[p][t].r >> 1;if(l <= mid) modify_add(ls, l, r, v, t);if(r > mid) modify_add(rs, l, r, v, t);update(p, t);
}
ll ask_sum(int p, int l, int r, int t)
{if(l <= tr[p][t].l && r >= tr[p][t].r){return tr[p][t].sum;}pushdown(p, t);int mid = tr[p][t].l + tr[p][t].r >> 1;ll ret = 0;if(l <= mid) ret += ask_sum(ls, l, r, t);if(r > mid) ret += ask_sum(rs, l, r, t);return ret;
}
ll ask_maxw(int p, int l, int r, int t)
{if(l <= tr[p][t].l && r >= tr[p][t].r){return tr[p][t].maxw;}pushdown(p, t);int mid = tr[p][t].l + tr[p][t].r >> 1;ll ret = -inf;if(l <= mid) ret = max(ret, ask_maxw(ls, l, r, t));if(r > mid) ret = max(ret, ask_maxw(rs, l, r, t));return ret;
}
int main()
{while(~scanf("%d%d", &n, &m)){rep(i, 1, n) A[i] = read();rep(i, 1, n) B[i] = read();rep(i, 1, n) S[i] = S[i - 1] + B[i];rep(i, 1, n) E[i] = A[i] - S[i];int op, a;ll b;build(1, 1, n, 0);build(1, 1, n, 1);while(m --){scanf("%d", &op);if(op == 1){scanf("%d%lld", &a, &b);ll v = b - A[a];A[a] = b;modify_add(1, a, a, v, 1);}else if(op == 2){scanf("%d%lld", &a, &b);ll v = b - B[a];B[a] = b;modify_add(1, a, n, v, 0);modify_add(1, a, n, -v, 1);}else{scanf("%d", &a);ll ans = max(ask_maxw(1, 1, a, 1), 0ll) + ask_sum(1, a, a, 0);printf("%lld\n", ans);}}}return 0;
}