Description
一家工厂一天可以产出a件商品,但是设备需要维修,维修前每天只能产出b件商品,维修需要k天,这k天没有产出,修好后就可以恢复正常每天a件,现在给出一些订单的日期和数量以及一些查询,每次查询给出一个维修开始日期p表示第p天开始维修在n天内最多可以接多少单,注意订单只能当天完成
Input
第一行输入五个整数n,k,a,b,q表示总天数,维修需要天数,设备正常时每天的产出,设备未维修时每天的产出以及操作数,之后m行每行一种操作,1 d v表示有一个订单在第d天下了v个订单,2 p表示在第p天开始维修查询最多可以接多少订单
(1<=k<=n<=2e5,1<=b < a<=1e4,1<=q<=2e5,1<=v<=1e4,1<=p<=n-k+1)
Output
对于每次查询,输出查询结果
Sample Input
5 2 2 1 8
1 1 2
1 5 3
1 2 1
2 2
1 4 2
1 3 2
2 1
2 3
Sample Output
3
6
4
Solution
开两个BIT分别记录设备正常和不正常时第i天的订单数,如果某天的订单总数超过a,那么在第一个BIT中只更新到a,同理如果某天的订单总数超过b,那么在第二个BIT中只更新到b,对于一次维修p,1~p-1这段时间能够完成的订单总数为第二个BIT中1~p-1段的和,p+k~n这段时间能够完成的订单总数为第一个BIT中p+k~n段的和,每次修改和查询都是O(logn),总时间复杂度O(qlogn)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 222222
int n,k,a,b,q,num[maxn];
struct BIT
{
#define lowbit(x) (x&(-x))
int b[maxn];
void init()
{
memset(b,0,sizeof(b));
}
void update(int x,int v)
{
while(x<=n)
{
b[x]+=v;
x+=lowbit(x);
}
}
int sum(int x)
{
int ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
}x,y;
int main()
{
while(~scanf("%d%d%d%d%d",&n,&k,&a,&b,&q))
{
memset(num,0,sizeof(num));
x.init(),y.init();
while(q--)
{
int op,d,v;
scanf("%d%d",&op,&d);
if(op==1)
{
scanf("%d",&v);
if(num[d]+v<=b)x.update(d,v),y.update(d,v);
else if(num[d]+v>b&&num[d]+v<=a)
{
if(num[d]<b)x.update(d,b-num[d]);
y.update(d,v);
}
else if(num[d]+v>=a)
{
if(num[d]<b)x.update(d,b-num[d]);
if(num[d]<a)y.update(d,a-num[d]);
}
num[d]+=v;
}
else
{
int ans=x.sum(d-1)-x.sum(0)+y.sum(n)-y.sum(d+k-1);
printf("%d\n",ans);
}
}
}
return 0;
}