Codeforces 627B Factory Repairs 线段树

题目:627B - Factory Repairs

Input

The first line contains five integers n, k, a, b, and q (1 ≤ k ≤ n ≤ 200 000, 1 ≤ b < a ≤ 10 000, 1 ≤ q ≤ 200 000) — the number of days, the length of the repair time, the production rates of the factory, and the number of updates, respectively.

The next q lines contain the descriptions of the queries. Each query is of one of the following two forms:

  • 1 di ai (1 ≤ di ≤ n, 1 ≤ ai ≤ 10 000), representing an update of ai orders on day di, or
  • 2 pi (1 ≤ pi ≤ n - k + 1), representing a question: at the moment, how many orders could be filled if the factory decided to commence repairs on day pi?

It's guaranteed that the input will contain at least one query of the second type.

Output

For each query of the second type, print a line containing a single integer — the maximum number of orders that the factory can fill over all n days.


题意:

有个工厂在n天内生产产品,本来机器是坏的,每天只能生产b件,修一次需要k天,修完后,每天可以生产a件,其中有q次询问,1开头,后面是d和ai,表示第d天有个ai的订单

2开头,后面有个d,表示这一天开始修理机器。每次2的时候,问工厂n天可以出售多少件产品?

分析:

线段树基础题型,1是单点增减,2是区间求和,sum二维数组分别维护修理前和修理后的生产效率,但是要注意都不可以超过订单额度,而且同一天可能有多个订单

区间求和的是修理前的天数和修理后的天数,相加即可

#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int n,k,a,b;
const int N=2e5+1;
int sum[N<<2][2];
void pushup(int rt)
{
    sum[rt][0]=sum[rt<<1][0]+sum[rt<<1|1][0];
    sum[rt][1]=sum[rt<<1][1]+sum[rt<<1|1][1];
}
void update(int d,int ai,int l,int r,int rt)
{
    if(d==l&&l==r){
        sum[rt][0]=ai+sum[rt][0]>b?b:ai+sum[rt][0];
        sum[rt][1]=ai+sum[rt][1]>a?a:ai+sum[rt][1];
        return;
    }
    int m=(l+r)>>1;
    if(d<=m)update(d,ai,lson);
    else update(d,ai,rson);
    pushup(rt);
}
int query(int L,int R,int id,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        return sum[rt][id];
    }
    int ans=0;
    int m=(l+r)>>1;
    if(L<=m)ans+=query(L,R,id,lson);
    if(m<R)ans+=query(L,R,id,rson);
    return ans;
}
int main()
{
    int q,op,d,ai;
    //freopen("f.txt","r",stdin);
   memset(sum,0,sizeof(sum));
    scanf("%d%d%d%d%d",&n,&k,&a,&b,&q);
    for(int i=0;i<q;i++){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d",&d,&ai);
            update(d,ai,1,n,1);
        }
        else{
            scanf("%d",&d);
           int ans=0;
           if(d>1)ans=query(1,d-1,0,1,n,1);
         //  cout<<ans<<endl;
           if(d+k<=n) ans+=query(d+k,n,1,1,n,1);
           printf("%d\n",ans);
        }
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值