SP1716 GSS3(线段树+矩阵乘法)
Code:
#include <bits/stdc++.h>
#define N 50001
#define ll long long
#define lson now<<1
#define rson now<<1|1
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll A[N];
struct Matrix
{
ll a[3][3];
ll*operator[](int x) { return a[x]; }
void re() { memset(a,0,sizeof(a));}
void Min() { for(int i=0;i<3;++i) for(int j=0;j<3;++j) a[i][j]=-inf; }
ll getmax() { return max(a[0][1], a[2][1]); }
}t[N<<2];
Matrix operator*(Matrix a,Matrix b)
{
int i,j,k;
Matrix c; c.Min();
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)for(k=0;k<3;++k) c[i][j]=max(c[i][j],a[i][k]+b[k][j]);
}
return c;
}
void pushup(int l,int r,int now)
{
t[now]=t[lson];
int mid=(l+r)>>1;
if(r>mid) t[now]=t[now]*t[rson];
}
void build(int l,int r,int now)
{
if(l==r)
{
t[now][0][0]=t[now][0][1]=t[now][2][0]=t[now][2][1]=A[l];
t[now][0][2]=t[now][1][0]=t[now][1][2]=-inf;
t[now][1][1]=t[now][2][2]=0;
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,lson);
if(r>mid) build(mid+1,r,rson);
pushup(l,r,now);
}
Matrix qmax(int l,int r,int now,int L,int R)
{
if(l>=L&&r<=R) return t[now];
int mid=(l+r)>>1;
Matrix re;
if(L<=mid)
{
re=qmax(l,mid,lson,L,R);
if(R>mid) re=re*qmax(mid+1,r,rson,L,R);
}
else
{
re=qmax(mid+1,r,rson,L,R);
}
return re;
}
void update(int l,int r,int now,int p,int v)
{
if(l==r)
{
A[p]=v;
t[now][0][0]=t[now][0][1]=t[now][2][0]=t[now][2][1]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,lson,p,v);
else update(mid+1,r,rson,p,v);
pushup(l,r,now);
}
int main()
{
// setIO("input");
int n,q,i,j;
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%lld",&A[i]);
build(1,n,1);
scanf("%d",&q);
for(i=1;i<=q;++i)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op==0)
{
update(1,n,1,l,r);
}
else
{
if(l>r) swap(l,r);
printf("%lld\n",qmax(1,n,1,l,r).getmax());
}
}
return 0;
}

浙公网安备 33010602011771号