修建道路(树状数组,区间修改,单点查询)

P5019

  • 应用树状数组维护差分数组
  • 遍历数组,找到一个非0的,在从这里往后找到0的,这中间就是区间修改的区间
  • 区间修改的值为这个区间的最小值,在第二步的时候可以顺便记录下来
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 10000001
int cha[MAX];
int n, now;
void add(int x, int k)
{
    for (; x <= n; x += x & -x)
    {
        cha[x] += k;
    }
}
ll query(int x)
{
    int ans = 0;
    for (; x; x -= x & -x)
    {
        ans += cha[x];
    }
    return ans;
}
void input()
{
    cin >> n;
    cin >> now;
    add(1, now);
    for (int i = 2; i <= n; i++)
    {
        int t;
        scanf("%d", &t);
        add(i, t - now);
        now = t;
    }
}
ll ans;
void work()
{
    int s = 1;
    while (true)
    {
        for (; s <= n && query(s) == 0; s++)
        {
        }
        if (s == n + 1)
        {
            printf("%lld", ans);
            exit(0);
        }
        int min_temp = 100000;
        int j = s;
        for (; j <= n; j++)
        {
            int temp = query(j);
            if (temp == 0)
            {
                break;
            }
            min_temp = min(min_temp, temp);
        }
        add(s, -min_temp);
        add(j, min_temp);
        ans += min_temp;
    }
}

int main()
{
    input();
    work();
}

 

posted on 2022-07-30 23:28  樵风  阅读(23)  评论(0)    收藏  举报