CF1635F Closest Pair
CF1635F Closest Pair
递增,考虑维护 。
考虑匹配,由 大的匹配 小的。
显然,单调,若 ,若 ,那么最优的匹配一定不是 。
故考虑维护每个点 ,记录左右边第一个满足 的 ,分别记作 和 ,单调栈经典操作。
此时,答案匹配只能是区间中所有 和 中最小的了,匹配方案 。
然后将询问按照右端点排序,维护左端点,线段树查询最小值即可。
时间复杂度 。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ha putchar(' ')
#define he putchar('\n')
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x * f;
}
inline void write(ll x)
{
if(x < 0)
{
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + 48);
}
const int _ = 3e5 + 10;
const ll inf = LLONG_MAX;
int n, m, w[_], x[_], L[_], R[_], t, q[_];
ll as[_], tr[_ << 2];
vector<int> d[_];
vector<pair<int, int>> qr[_];
void build(int o, int l, int r)
{
tr[o] = inf;
if(l == r) return;
int mid = (l + r) >> 1;
build(o << 1, l, mid), build(o << 1 | 1, mid + 1, r);
}
void upd(int o, int l, int r, int p, ll v)
{
if(l == r) return tr[o] = min(tr[o], v), void();
int mid = (l + r) >> 1;
if(p <= mid) upd(o << 1, l, mid, p, v);
else upd(o << 1 | 1, mid + 1, r, p, v);
tr[o] = min(tr[o << 1], tr[o << 1 | 1]);
}
ll qry(int o, int l, int r, int L, int R)
{
if(L <= l && r <= R) return tr[o];
int mid = (l + r) >> 1; ll res = inf;
if(L <= mid) res = qry(o << 1, l, mid, L, R);
if(R > mid) res = min(res, qry(o << 1 | 1, mid + 1, r, L, R));
return res;
}
signed main()
{
n = read(), m = read();
for(int i = 1; i <= n; ++i) x[i] = read(), w[i] = read();
t = 0;
for(int i = 1; i <= n; ++i)
{
while(t && w[q[t]] > w[i]) t--;
L[i] = q[t];
q[++t] = i;
}
t = 0;
for(int i = n; i >= 1; --i)
{
while(t && w[q[t]] > w[i]) t--;
R[i] = q[t];
q[++t] = i;
}
for(int i = 1, l, r; i <= m; ++i)
{
l = read(), r = read();
qr[r].push_back({l, i});
}
for(int i = 1; i <= n; ++i)
{
if(L[i]) d[i].push_back(L[i]);
if(R[i]) d[R[i]].push_back(i);
}
build(1, 1, n);
for(int i = 1; i <= n; ++i)
{
for(int j : d[i]) upd(1, 1, n, j, 1ll * abs(x[i] - x[j]) * (w[i] + w[j]));
for(pair<int, int> j : qr[i]) as[j.second] = qry(1, 1, n, j.first, i);
}
for(int i = 1; i <= m; ++i) write(as[i]), he;
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121998