题目
题意:
有n个连续的一维上的点,每个点有一个美丽值。
每次有三种操作:
1、将x点的美丽值改为y。
2、将x、y交换
3、查询[x y]间,连续k个点的美丽值总和的最大值。
解法:
线段树,叶子i表示[i i+k]美丽值总和,然后每个点维护一个区间最大值。
修改时区间修改,将包含x的所有叶子都修改(用lazy标记),查询时输出区间最大值。
Time:344ms Memory:5348KB Length:2732B #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <map> #include <queue> #include <set> #include <sstream> #define DBLE 1e-8 #define PI 3.1415926535898 #define INF 1000000000 #define MAXN (1<<18) #define MP(x,y) (make_pair((x),(y))) #define FI first #define SE second using namespace std; int sum[MAXN],node[MAXN]; int tree[MAXN*2],lazy[MAXN*2]; int n,m,k; void build(int pos,int l,int r) { tree[pos]=-INF; if(l==r) { tree[pos]=sum[l+k-1]-sum[l-1]; return ; } int mid=(l+r)/2; build(pos*2,l,mid); build(pos*2+1,mid+1,r); tree[pos]=max(tree[pos*2],tree[pos*2+1]); } void cha(int pos,int l,int r,int dl,int dr,int num) { if(lazy[pos]) { tree[pos]+=lazy[pos]; if(l!=r) { lazy[pos*2]+=lazy[pos]; lazy[pos*2+1]+=lazy[pos]; } lazy[pos]=0; } if(dl<=l&&dr>=r) { if(l!=r) { lazy[pos*2]+=num; lazy[pos*2+1]+=num; } tree[pos]+=num; return ; } else if(dr<l||dl>r) return ; int mid=(l+r)/2; cha(pos*2,l,mid,dl,dr,num); cha(pos*2+1,mid+1,r,dl,dr,num); tree[pos]=max(tree[pos*2],tree[pos*2+1]); } int mfind(int pos,int l,int r,int dl,int dr) { int ans; if(lazy[pos]) { tree[pos]+=lazy[pos]; if(l!=r) { lazy[pos*2]+=lazy[pos]; lazy[pos*2+1]+=lazy[pos]; } lazy[pos]=0; } if(dl<=l&&dr>=r) return tree[pos]; else if(dr<l||dl>r) return -INF; int mid=(l+r)/2; ans=max(mfind(pos*2,l,mid,dl,dr),mfind(pos*2+1,mid+1,r,dl,dr)); tree[pos]=max(tree[pos*2],tree[pos*2+1]); return ans; } int main() { //freopen("J:\\MyDocument\\Code\\input.txt","r",stdin); int ncase,a,b,c; scanf("%d",&ncase); while(ncase--) { memset(lazy,0,sizeof(lazy)); scanf("%d%d%d",&n,&m,&k); sum[0]=0; for(int i=1;i<=n;++i) scanf("%d",&node[i]),sum[i]=sum[i-1]+node[i]; build(1,1,n-k+1); n=n-k+1; while(m--) { scanf("%d%d%d",&a,&b,&c); if(a==1) { cha(1,1,n,max(b-k+1,1),min(b,n),node[c]-node[b]); swap(b,c); cha(1,1,n,max(b-k+1,1),min(b,n),node[c]-node[b]); swap(node[b],node[c]); } else if(a==0) { cha(1,1,n,max(b-k+1,1),min(b,n),c-node[b]); node[b]=c; } else printf("%d\n",mfind(1,1,n,b,c-k+1)); } } return 0; }