用线段树维护三个和,维护之前能生产多少,维护之后能生产多少,最大限制生产多少
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 200005;
struct node{
int l,r;
int sum[3];
}segTree[maxn << 2];
int a,b;
void pushup(int num){
for(int i = 0; i < 3; i++){
segTree[num].sum[i] = segTree[num << 1].sum[i] + segTree[num << 1 | 1].sum[i];
}
}
void build(int num,int l,int r){
segTree[num].l = l;
segTree[num].r = r;
for(int i = 0; i < 3; i++){
segTree[num].sum[i] = 0;
}
if(l == r){
return ;
}
int mid = (l + r) >> 1;
build(num << 1,l,mid);
build(num << 1 | 1,mid + 1,r);
}
void update(int num,int pos,int v){
if(segTree[num].l == segTree[num].r){
int add = segTree[num].sum[2] + v;
segTree[num].sum[0] = min(b,add);
segTree[num].sum[1] = min(a,add);
segTree[num].sum[2] = add;
return;
}
int mid = (segTree[num].l + segTree[num].r) >> 1;
if(pos <= mid){
update(num << 1,pos,v);
}
else{
update(num << 1 | 1,pos,v);
}
pushup(num);
}
int query(int num,int l,int r,int ty){
if(l > r){
return 0;
}
if(l == segTree[num].l && r ==segTree[num].r){
return segTree[num].sum[ty];
}
int mid = (segTree[num].l + segTree[num].r) >> 1;
if(r <= mid){
return query(num << 1,l,r,ty);
}
else if(l > mid){
return query(num << 1 | 1,l,r,ty);
}
else{
return query(num << 1,l,mid,ty) + query(num << 1 | 1,mid + 1,r,ty);
}
}
int main(void){
int n,k,q;
scanf("%d%d%d%d%d",&n,&k,&a,&b,&q);
build(1,1,n);
while(q--){
int op;
scanf("%d",&op);
if(op == 1){
int d,a;
scanf("%d%d",&d,&a);
update(1,d,a);
}
else{
int p;
scanf("%d",&p);
printf("%d\n",query(1,1,p-1,0) + query(1,p + k,n,1));
}
}
return 0;
}