L3-017 森森快递 (30 分)
思路:
类似于这个题
先贪心的将区间排序保证按顺序处理区间可以得到最优解,然后对于每个区间查询区间最小值
M
i
n
Min
Min,
M
i
n
>
0
Min>0
Min>0 则区间可以选择修改,修改操作为区间所有数减去最小值
E题也是这么贪的
推一下巨佬博客
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 1e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
#define ls p << 1
#define rs p << 1 | 1
ll tr[maxn << 2], mark[maxn << 2];
struct node{
int l, r;
bool operator<(const node &B)const{
//if(r != B.r) return l > B.l;
//else
return r < B.r;// 实际上只贪右端点就可以ac
}
}a[maxn];
void modify(int p, ll d){
tr[p] += d;
mark[p] += d;
}
void pushdown(int p){
if(!mark[p]) return;
modify(ls, mark[p]);
modify(rs, mark[p]);
mark[p] = 0;
}
void pushup(int p){
tr[p] = min(tr[ls], tr[rs]);
}
void build(int p = 1, int cl = 1, int cr = n){
if(cl == cr){
cin >> tr[p]; return;
}
int mid = cl + cr >> 1;
build(ls, cl, mid);
build(rs, mid + 1, cr);
pushup(p);
}
ll qry(int l, int r, int p = 1, int cl = 1, int cr = n){
if(cl >= l && cr <= r) return tr[p];
pushdown(p);
int mid = cl + cr >> 1;
ll ans = INF;// 查询最小值记得初始化正无穷,不要忘!!!
if(mid >= l) ans = min(ans, qry(l, r, ls, cl, mid));
if(mid < r) ans = min(ans, qry(l, r, rs, mid + 1, cr));
return ans;
}
void update(int l, int r, int d, int p = 1, int cl = 1, int cr = n){
if(cl >= l && cr <= r){
modify(p, d); return;
}
pushdown(p);
int mid = cl + cr >> 1;
if(mid >= l) update(l, r, d, ls, cl, mid);
if(mid < r) update(l, r, d, rs, mid + 1, cr);
pushup(p);
}
void work()
{
cin >> n >> m;
--n;
build();
for(int i = 1; i <= m; ++i){
cin >> a[i].l >> a[i].r;
if(a[i].l > a[i].r) swap(a[i].l, a[i].r);
}
sort(a + 1, a + 1 + m);
ll ans = 0;
for(int i = 1; i <= m; ++i){
int l = a[i].l, r = a[i].r;
++l, ++r;
ll d = qry(l, r - 1);
if(d > 0)
ans += d, update(l, r - 1, -d);
}
cout << ans;
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}