给出一个n个元素的序列,序列有正数也有负数
支持3个操作:
p x y
0.p=0时,把第x个的值改为y
1.p=1时,交换第x个和第y个的值
2.p=2时,问区间[x,y]里面连续k个的子序列的最大和(保证y-x+1>=k)
我们只要定义数组v
v[i]表示原序列中,从第i个开始,连续k个元素的值的和
然后我们只需要维护一棵线段树,树的叶子节点表示数组v
树的节点维护:
区间[l,r]中,连续k个的子序列的最大和,即数组v的最大值
这样的话,3个操作就变为:
0.把区间[max(x-k+1,0),x]的值加y-init_v[x]
1.区间[max(x-k+1,0),x]加上init_v[y]-init_v[x]
区间[max(y-k+1,0),y]加上init_v[x]-init_v[y]
交换init_v[x]和init_v[y]的值
2.求max[x,y-k+1]
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 7 #define ll long long 8 #define lson l,m,rt<<1 9 #define rson m+1,r,rt<<1|1 10 11 const int maxn=200000+5; 12 const int inf=0x3f3f3f3f; 13 14 int init_v[maxn]; 15 int init_sum[maxn]; 16 int v[maxn<<2]; 17 int lazy[maxn<<2]; 18 int n,m,k; 19 20 void solve(); 21 22 int main() 23 { 24 int test; 25 scanf("%d",&test); 26 while(test--){ 27 scanf("%d %d %d",&n,&m,&k); 28 for(int i=1;i<=n;i++){ 29 scanf("%d",&init_v[i]); 30 } 31 solve(); 32 } 33 return 0; 34 } 35 36 void pushup(int rt) 37 { 38 v[rt]=max(v[rt<<1],v[rt<<1|1]); 39 } 40 41 void pushdown(int rt) 42 { 43 if(lazy[rt]){ 44 lazy[rt<<1]+=lazy[rt]; 45 lazy[rt<<1|1]+=lazy[rt]; 46 v[rt<<1]+=lazy[rt]; 47 v[rt<<1|1]+=lazy[rt]; 48 lazy[rt]=0; 49 } 50 } 51 52 void build(int l,int r,int rt) 53 { 54 if(l==r){ 55 v[rt]=init_sum[l+k-1]-init_sum[l-1]; 56 return ; 57 } 58 int m=(l+r)>>1; 59 build(lson); 60 build(rson); 61 pushup(rt); 62 } 63 64 void update(int L,int R,int add,int l,int r,int rt) 65 { 66 if(L<=l&&R>=r){ 67 lazy[rt]+=add; 68 v[rt]+=add; 69 return ; 70 } 71 int m=(l+r)>>1; 72 pushdown(rt); 73 if(L<=m) 74 update(L,R,add,lson); 75 if(R>m) 76 update(L,R,add,rson); 77 pushup(rt); 78 } 79 80 int query(int L,int R,int l,int r,int rt) 81 { 82 if(L<=l&&R>=r){ 83 return v[rt]; 84 } 85 int m=(l+r)>>1; 86 pushdown(rt); 87 int ret=-inf; 88 if(L<=m) 89 ret=max(ret,query(L,R,lson)); 90 if(R>m) 91 ret=max(ret,query(L,R,rson)); 92 93 return ret; 94 } 95 96 void solve() 97 { 98 init_sum[0]=0; 99 for(int i=1;i<=n;i++){ 100 init_sum[i]=init_sum[i-1]+init_v[i]; 101 } 102 103 build(1,n,1); 104 memset(lazy,0,sizeof lazy); 105 for(int i=1;i<=m;i++){ 106 int p,x,y; 107 scanf("%d %d %d",&p,&x,&y); 108 if(p==0){ 109 update(max(x-k+1,0),x,y-init_v[x],1,n,1); 110 init_v[x]=y; 111 } 112 else if(p==1){ 113 update(max(x-k+1,0),x,init_v[y]-init_v[x],1,n,1); 114 update(max(y-k+1,0),y,init_v[x]-init_v[y],1,n,1); 115 swap(init_v[x],init_v[y]); 116 } 117 else{ 118 printf("%d\n",query(x,y-k+1,1,n,1)); 119 } 120 } 121 return ; 122 }
时间: 2024-10-17 01:12:49