题目描述
题意:
有两个序列,
操作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;
}