题目链接:点击查看
题意:
给出一个N个数的序列以及一个k(0<k<=n<=200000),m个操作p,x,y,其中
p=0:将x位置的数替换为y
p=1:将x y位置的数互换
p=2: 查询x-y位置区间连续k个数的和的最大值
题解:每个位置向前取k个数,作为这个位置的结果,线段树维护下每个区间的最大值即可,当改变一个位置p 的数时,把他所影响的区间(p,p+k-1)更新一下即可,查询(x,y)区间时,查询(x+k-1,y)的最大值即可
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200100;
struct node{
int l,r;
int laz;
int maxx;
}tree[N<<2];
int sum[N],a[N];
int n,m,k;
void pushup(int cur)
{
tree[cur].maxx=max(tree[cur<<1].maxx,tree[cur<<1|1].maxx);
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
tree[cur].laz=0;
if(l==r)
{
if(l<k) tree[cur].maxx=-1e9;
else tree[cur].maxx=sum[l]-sum[l-k];
return ;
}
int mid=(r+l)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
pushup(cur);
}
void pushdown(int cur)
{
if(tree[cur].laz!=0)
{
tree[cur<<1|1].maxx+=tree[cur].laz;
tree[cur<<1|1].laz+=tree[cur].laz;
tree[cur<<1].maxx+=tree[cur].laz;
tree[cur<<1].laz+=tree[cur].laz;
tree[cur].laz=0;
}
}
void update(int pl,int pr,int cur,int val)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
tree[cur].maxx+=val;
tree[cur].laz+=val;
return;
}
pushdown(cur);
if(pl<=tree[cur<<1].r) update(pl,pr,cur<<1,val);
if(pr>=tree[cur<<1|1].l) update(pl,pr,cur<<1|1,val);
pushup(cur);
}
int query(int pl,int pr,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
return tree[cur].maxx;
}
int res=-1e9;
pushdown(cur);
if(pl<=tree[cur<<1].r) res=max(res,query(pl,pr,cur<<1));
if(pr>=tree[cur<<1|1].l) res=max(res,query(pl,pr,cur<<1|1));
return res;
}
int main()
{
int T;
int x,y,ll,rr,xx,yy;
int op;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
build(1,n,1);
while(m--)
{
scanf("%d%d%d",&op,&x,&y);
if(op==0)
{
ll=max(k,x);
rr=min(n,x+k-1);
if(ll<=rr)update(ll,rr,1,y-a[x]);
a[x]=y;
}
else if(op==1)
{
if(x>y) swap(x,y);
ll=max(k,x);
rr=min(n,x+k-1);
if(ll<=rr) update(ll,rr,1,a[y]-a[x]);
ll=max(k,y);
rr=min(n,y+k-1);
if(ll<=rr) update(ll,rr,1,a[x]-a[y]);
swap(a[x],a[y]);
}
else
{
printf("%d\n",query(x+k-1,y,1));
}
}
}
return 0;
}