Codeforces 635D Factory Repairs【树状数组】

又是看了很久的题目。。。


题目链接:

http://codeforces.com/contest/635/problem/D

题意:

一家工厂生产维修之前每天生产b个,维修了k天之后每天生产a个,维修期间不生产。
若干操作:
1. 1 d aa 第d天要求aa个订单,一个订单对应一个物品,必须在这一天中完成。
2. 2 d 第d天开始维修,最终能得到多少订单。

分析:

树状数组分别维护维修前和维修后得到的订单数,这样对于不同的维修日期,把这两种相加即可。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define pr(x) cout << #x << ": " << x << "  "
#define pl(x) cout << #x << ": " << x << endl;
#define sa(x) scanf("%d",&(x))
#define mdzz cout<<"mdzz"<<endl;
const int maxn = 2e5 + 5, oo =0x3f3f3f3f;
typedef long long ll;
int bita[maxn], bitb[maxn], cnt[maxn];//a维修后b维修前
int n;
int suma(int i)
{
    int ans = 0;
    while(i){
        ans += bita[i];
        i -= i & -i;
    }
    return ans;
}
int sumb(int i)
{
    int ans = 0;
    while(i){
        ans += bitb[i];
        i -= i & -i;
    }
    return ans;
}
void adda(int i, int x)
{
    while(i <= n){
        bita[i] += x;
        i += i &-i;
    }
}
void addb(int i, int x)
{
    while(i <= n){
        bitb[i] += x;
        i += i &-i;
    }
}
int main (void)
{
    int k, a, b, q;sa(n);sa(k);sa(a);sa(b);sa(q);
    int aa, d;
    int ans = 0;
    for(int i = 0; i < q; i++){
        int type;sa(type);
        if(type == 1){
            scanf("%d%d", &d, &aa);
            adda(d, -min(cnt[d], a)); addb(d, -min(cnt[d], b));//复原
            cnt[d] += aa;
            adda(d, min(cnt[d], a)); addb(d, min(cnt[d], b));
        }else{
            sa(d);
            ans += sumb(d - 1) + suma(n) - suma(d + k - 1);
            printf("%d\n", ans);
            ans = 0;
        }
    }
    return 0;
}
posted @ 2016-05-10 13:14  zhuyujiang  阅读(195)  评论(0编辑  收藏  举报