HDU - 6315 - Naive Operations
题意:
有两个数列a,b,均有n个数,b是1~n的一个排列,a均为0
有两个操作:
add l r:a数组 [l, r] 区间内的数+1
query l r:求∑⌊ai/bi⌋ (l <= i <= r)
一共维护区间最大值,区间最小值,区间和三个数据
当+1时,先区间更新
记a区间最大值为 mx ,b区间最小值为 mi, 当区间中mx >= mi 时可能会区间和+1,所以向下更新到单点
若区间和+1则mi[i] += b[i]
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
int n, q;
int b[maxn];
char op[10];
int sum[maxn<<2], mi[maxn<<2], mx[maxn<<2], lazy[maxn<<2];
void Pushdown(int x)
{
if(lazy[x])
{
mx[x<<1] += lazy[x];
mx[x<<1|1] += lazy[x];
lazy[x<<1] += lazy[x];
lazy[x<<1|1] += lazy[x];
lazy[x] = 0;
}
}
void Pushup(int x)
{
sum[x] = sum[x<<1] + sum[x<<1|1];
mi[x] = min(mi[x<<1], mi[x<<1|1]);
mx[x] = max(mx[x<<1], mx[x<<1|1]);
}
void build(int x,int l,int r)
{
if(l == r)
{
mx[x] = sum[x] = 0;
mi[x] = b[l];
return;
}
int mid = (l+r) >> 1;
build(x<<1, l, mid);
build(x<<1|1, mid+1, r);
Pushup(x);
}
void Update2(int x,int l,int r)
{
if(l == r)
{
if(mx[x] >= mi[x])
{
mi[x] += b[l];
sum[x] ++;
}
return;
}
Pushdown(x);
if(mx[x] >= mi[x])
{
int mid = (l+r)>>1;
Update2(x<<1, l, mid);
Update2(x<<1|1, mid+1, r);
Pushup(x);
}
}
void Update(int x,int l,int r,int L,int R)
{
if(L<=l && r<=R)
{
mx[x] ++;
lazy[x] ++;
if(mx[x] >= mi[x])
Update2(x, l, r);
return;
}
Pushdown(x);
int mid = (l+r)>>1;
if(L <= mid)
Update(x<<1, l, mid, L, R);
if(R > mid)
Update(x<<1|1, mid+1, r, L, R);
Pushup(x);
}
int Sum(int x,int l,int r,int L,int R)
{
if(L<=l && r<=R)
return sum[x];
int ans = 0, mid = (l+r)>>1;
if(L<=mid)
ans += Sum(x<<1, l, mid, L, R);
if(R>mid)
ans += Sum(x<<1|1, mid+1, r, L, R);
return ans;
}
int main()
{
while(scanf("%d%d",&n,&q)!=EOF)
{
memset(lazy, 0, sizeof lazy);
for(int i=1; i<=n; i++)
scanf("%d", &b[i]);
build(1, 1, n);
for(int i=1; i<=q; i++)
{
int x, y;
scanf("%s%d%d", op, &x, &y);
if(op[0] == 'a')
Update(1, 1, n, x, y);
else
printf("%d\n", Sum(1, 1, n, x, y));
}
}
return 0;
}