HDU - 6315 - Naive Operations(线段树区间更新 + 单点更新)

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 <iostream>
#include <string.h>
#include <stdio.h>

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;
}

猜你喜欢

转载自blog.csdn.net/w326159487/article/details/81226037
今日推荐