版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w144215160044/article/details/51386163
http://codeforces.com/contest/627/problem/B
题意:有n个机器,机器非正常时每天生产b个物品,正常时每天生产a个物品,维修机器需要花费连续的k天(这k天什么都不能做)。有q次操作
1 a d,表示在d天有a个要求(每个要求需要一个物品)
2 p,表示从p天开始维修。(每一次维修是独立的)
机器初始是非正常的。
对每一个2操作,输出最多可以满足的要求数。
线段树,一个数组分别保存维修前和维修后能生产多少就ok了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 201000
#define met(a, b) memset(a, b, sizeof(a))
const double PI = acos(-1.0);
typedef long long LL;
struct node
{
int l, r, flag;
LL num[4];
}tree[N*4];
LL a, b;
void Build (int rt, int l, int r)
{
tree[rt].l = l, tree[rt].r = r;
for (int i=0; i<2; i++)
tree[rt].num[i] = 0;
if (l==r) return;
int mid = (l+r)/2;
Build (rt<<1, l, mid);
Build (rt<<1|1, mid+1, r);
}
void UP (int rt)
{
for (int i=0; i<2; i++)
tree[rt].num[i] = tree[rt<<1].num[i] + tree[rt<<1|1].num[i];
}
void Update (int rt, int k, LL e)
{
if (tree[rt].l == tree[rt].r)
{
tree[rt].num[0] = min (tree[rt].num[0]+e, b);
tree[rt].num[1] = min (tree[rt].num[1]+e, a);
return;
}
int mid = (tree[rt].l+tree[rt].r)/2;
if (k <= mid) Update (rt<<1, k, e);
else Update (rt<<1|1, k, e);
UP (rt);
}
LL Query (int rt, int l, int r, LL e)
{
if (l > r) return 0;
if (tree[rt].l==l && tree[rt].r==r)
return tree[rt].num[e];
int mid = (tree[rt].l+tree[rt].r)/2;
if (r <= mid)
return Query (rt<<1, l, r, e);
else if (l > mid)
return Query (rt<<1|1, l, r, e);
else
return Query (rt<<1, l, mid, e) + Query (rt<<1|1, mid+1, r, e);
}
int main ()
{
int n, k, q;
while (scanf ("%d %d %I64d %I64d %d", &n, &k, &a, &b, &q) != EOF)
{
Build (1, 1, n);
while (q--)
{
LL x, y, z, ans1, ans2;
scanf ("%I64d", &x);
if (x==1)
{
scanf ("%I64d %I64d", &y, &z);
Update (1, y, z);
}
else
{
scanf ("%I64d", &y);
ans1 = Query (1, 1, y-1, 0);
ans2 = Query (1, y+k, n, 1);
printf ("%I64d\n", ans1+ans2);
}
}
}
return 0;
}