给出一个数组b[i],一个初始为0得a[i],两个操作add l r把a[l] - a[r]都加1,query l r求a[i]/b[i]的和
用一个数组维护(a[i] + ti ) / b[i]中的ti, ti初始等于b[i]每add一次ti就减一,当ti为0得时候维护a[i]/b[i]的地方+1,并把ti重置为b[i]
下推lazy地时候写错了写成了tree[rt<<1].lazy = tree[rt].lazy,这里应该写+=才对
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define ls rt<<1
#define rs rt<<1|1
const int mx = 1e5+5;
int b[mx],n,q;
struct node
{
int l, r, sum, min, lazy;
}tree[mx<<2];
void build(int rt,int l, int r)
{
tree[rt].sum = 0;
tree[rt].lazy = 0;
tree[rt].l = l;
tree[rt].r = r;
if (l == r)
{
tree[rt].min = b[l];
return ;
}
int m = (l + r) / 2;
build(ls,l,m);
build(rs,m+1,r);
tree[rt].min = min(tree[ls].min, tree[rs].min);
}
void PushUp(int rt)
{
tree[rt].sum = tree[ls].sum + tree[rs].sum;
tree[rt].min = min(tree[ls].min, tree[rs].min);
}
void PushDown(int rt)
{
if (tree[rt].lazy)
{
tree[ls].min -= tree[rt].lazy;
tree[rs].min -= tree[rt].lazy;
tree[ls].lazy += tree[rt].lazy;
tree[rs].lazy += tree[rt].lazy;
tree[rt].lazy = 0;
}
}
void change(int rt)
{
if (tree[rt].l == tree[rt].r)
{
tree[rt].sum++;
tree[rt].min = b[tree[rt].l];
return ;
}
PushDown(rt);
if (tree[ls].min == 0)
change(ls);
if (tree[rs].min == 0)
change(rs);
PushUp(rt);
}
void update(int l,int r,int rt)
{
if (tree[rt].l == l && tree[rt].r == r)
{
tree[rt].min--;
tree[rt].lazy++;
if (tree[rt].min == 0)
change(rt);
return ;
}
PushDown(rt);
int m = (tree[rt].l + tree[rt].r) / 2;
if (m >= r) update(l,r,ls);
else if (m+1 <= l) update(l,r,rs);
else
{
update(l,m,ls);
update(m+1,r,rs);
}
PushUp(rt);
}
ll query(int rt,int l, int r)
{
if (tree[rt].l == l && tree[rt].r == r)
return tree[rt].sum;
PushDown(rt);
int m = (tree[rt].l + tree[rt].r) / 2;
ll ans = 0;
if (m >= r) ans += query(ls, l, r);
else if (m+1 <= l) ans += query(rs,l,r);
else
{
ans += query(ls,l,m);
ans += query(rs,m+1,r);
}
return ans;
}
int main()
{
// freopen("1007.in","r",stdin);
// freopen("out.txt","w",stdout);
while (scanf("%d%d",&n,&q) != EOF)
{
memset(b,0,sizeof(b));
for (int i = 1; i <= n; i++)
scanf("%d",&b[i]);
build(1,1,n);
char op[12];
int x, y;
for (int i = 1; i <= q; i++)
{
scanf("%s%d%d",op,&x,&y);
if (op[0] == 'a') update(x,y,1);
else printf("%lld\n",query(1,x,y));
}
}
return 0;
}