一开始死刚DP,刚了半天感觉不大对劲,好像不大像dp,突然发现原来这不就是一个线段吗= =,维护一下左边右边是否选择就好了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
typedef long long ll;
struct node
{
int l,r,v,lc,rc,mx;
ll f[2][2];
}t[N*10];
ll ans;
int n,m,cnt,q;
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
t[x].lc=t[x].rc=-1;
if (l==r)return;
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
}
inline void pushdown(int x)
{
t[x].f[0][0]=max(t[x<<1].f[0][1]+t[x<<1|1].f[0][0],t[x<<1].f[0][0]+t[x<<1|1].f[1][0]);
t[x].f[1][0]=max(t[x<<1].f[1][1]+t[x<<1|1].f[0][0],t[x<<1].f[1][0]+t[x<<1|1].f[1][0]);
t[x].f[0][1]=max(t[x<<1].f[0][1]+t[x<<1|1].f[0][1],t[x<<1].f[0][0]+t[x<<1|1].f[1][1]);
t[x].f[1][1]=max(t[x<<1].f[1][1]+t[x<<1|1].f[0][1],t[x<<1].f[1][0]+t[x<<1|1].f[1][1]);
}
inline void change(int x,int pos,ll v)
{
if (t[x].l==t[x].r)
{
t[x].f[1][1]=v;
t[x].mx=v;
return;
}
int mid=(t[x].l+t[x].r)>>1;
if (pos<=mid)change(x<<1,pos,v);
else change(x<<1|1,pos,v);
pushdown(x);
t[x].mx=max(t[x].f[0][0],t[x].f[0][1]);
t[x].mx=max(1ll*t[x].mx,max(t[x].f[1][0],t[x].f[1][1]));
}
int main()
{
scanf("%d%d",&n,&q);
build(1,1,n);
fo(i,1,n)
{
ll x;
scanf("%lld",&x);
change(1,i,x);
}
ans=0;
while (q--)
{
ll x,c;
scanf("%lld%lld",&x,&c);
change(1,x,c);
ans+=t[1].mx;
}
printf("%lld\n",ans);
}