修建道路(树状数组,区间修改,单点查询)
- 应用树状数组维护差分数组
- 遍历数组,找到一个非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();
}