Loading

「KTSC 2020 R1」穿越 做题记录

此处应该有「笔记」。link

对于 \(n\le 2500\) 的分数是容易的:设 \(f_{i, j}\) 表示从 \((0,\_)\) 走到 \((j,\_)\)\(i\) 段的情况下穿越障碍物的最小次数,最后求个凸包来查询。

使用线段树可以做到 \(\mathcal O(n ^ 2 \log n)\)

我太菜了,所以对于一个大小为 \(V\times V\) 的平面的整点构成的凸包(其中不存在三个点在一条直线上)中的点数为 \(\mathcal O(V ^ {\frac 23})\)

证明可以看这里,感觉很厉害。

所以我们可以把 \(i\) 这一维和 \(f_{i, j}\) 的值域维捆起来丢在一个平面上。

很显然,我们只关心凸包上的点,所以线段树每个点维护一个凸包,合并是对位 min。

由于凸包的点数为 \(\mathcal O(n ^ {\frac 23})\),所以时间复杂度为 \(\mathcal O(n ^ {\frac 53} \log n)\)

点击查看代码
#include <bits/stdc++.h>
#define ll int
#define LL long long
#define uLL unsigned LL
#define fi first
#define se second
#define mkp make_pair
#define pir pair <ll, ll>
#define pb emplace_back
#define i128 __int128
const ll maxn = 2e4 + 10, mod = 998244353, M = 1e6 + 10, inf = 1e9;
template <class T>
void rd(T &x) {
	char ch; ll f = 0;
	while(!isdigit(ch = getchar()))
		if(ch == '-') f = 1;
	x = ch - '0';
	while(isdigit(ch = getchar()))
		x = (x << 1) + (x << 3) + ch - '0';
	if(f) x = -x;
}
ll power(ll a, ll b = mod - 2, ll p = mod) {
	ll s = 1;
	while(b) {
		if(b & 1) s = 1ll * s * a % p;
		a = 1ll * a * a % p, b >>= 1;
	} return s;
}
template <class T1, class T2>
void add(T1 &x, const T2 y) { x = x + y >= mod? x + y - mod : x + y; }
template <class T1, class T2>
void sub(T1 &x, const T2 y) { x = x < y? x + mod - y : x - y; }
template <class T1, class T2>
ll pls(const T1 x, const T2 y) { return x + y >= mod? x + y - mod : x + y; }
template <class T1, class T2>
ll mus(const T1 x, const T2 y) { return x < y? x + mod - y : x - y; }
template <class T1, class T2>
void chkmax(T1 &x, const T2 y) { x = x < y? y : x; }
template <class T1, class T2>
void chkmin(T1 &x, const T2 y) { x = x < y? x : y; }
using namespace std;

ll n, m, l[maxn], r[maxn], h[maxn], ht;
struct point { ll x, y; point(ll X = 0, ll Y = 0) { x = X, y = Y; } };
#define Convex vector <point>
const Convex operator + (const Convex &a, const Convex &b) {
	Convex c;
	ll i = 0, j = 0;
	while(i < a.size() || j < b.size()) {
		point tmp;
		if(i < a.size() && (j == b.size() || a[i].x <= b[j].x)) tmp = a[i++];
		else tmp = b[j++];
		if(!c.empty() && c.back().x == tmp.x && c.back().y <= tmp.y) continue;
		while(c.size() > 1) {
			point bk = c.back(), sd = c[c.size() - 2];
			if(1ll * (tmp.x - bk.x) * (bk.y - sd.y)
			 >= 1ll * (tmp.y - bk.y) * (bk.x - sd.x)) c.pop_back();
			else break;
		}
		c.pb(tmp);
	} return c;
}
const Convex mov(const Convex &a, const ll dx, const ll dy) {
	Convex b = a;
	for(point &tmp: b) tmp.x += dx, tmp.y += dy;
	return b;
}

struct SGT {
	Convex mn[maxn << 2], tag[maxn << 2]; ll add[maxn << 2];
	void addtag(ll p, ll k, const Convex &tg) {
		if(k) mn[p] = mov(mn[p], 0, k), tag[p] = mov(tag[p], 0, k);
		mn[p] = mn[p] + tg, tag[p] = tag[p] + tg, add[p] += k;
	}
	void pushdown(ll p) {
		if(tag[p].empty()) return;
		addtag(p << 1, add[p], tag[p]), addtag(p << 1|1, add[p], tag[p]);
		Convex().swap(tag[p]), add[p] = 0;
	}
	void modify(ll p, ll l, ll r, ll ql, ll qr) {
		if(ql <= l && r <= qr) return addtag(p, 1, {});
		pushdown(p); ll mid = l + r >> 1;
		if(ql <= mid) modify(p << 1, l, mid, ql, qr);
		if(mid < qr) modify(p << 1|1, mid + 1, r, ql, qr);
		mn[p] = mn[p << 1] + mn[p << 1|1];
	}
} tr;
Convex res;

void init(ll N, ll M, vector <ll> Y1, vector <ll> Y2) {
	n = N, m = M;
	h[++ht] = 1, h[++ht] = M + 1;
	for(ll i = 1; i <= n; i++) {
		l[i] = Y1[i - 1] + 1, r[i] = Y2[i - 1] + 1;
		h[++ht] = l[i], h[++ht] = r[i] + 1;
	}
	sort(h + 1, h + 1 + ht);
	ht = unique(h + 1, h + 1 + ht) - h - 2;
	for(ll i = 1; i <= 4 * ht; i++)
		tr.mn[i] = {point(0, 0)};
	for(ll i = 1; i <= n; i++) {
		l[i] = lower_bound(h + 1, h + 1 + ht, l[i]) - h;
		r[i] = upper_bound(h + 1, h + 1 + ht, r[i]) - h - 1;
		tr.modify(1, 1, ht, l[i], r[i]);
		tr.addtag(1, 0, mov(tr.mn[1], 1, 0));
	}
	res = tr.mn[1];
}

LL minimize(ll A, ll B) {
	ll lo = 0, hi = res.size() - 2;
	while(lo <= hi) {
		ll mid = lo + hi >> 1;
		if(1ll * A * res[mid].x + 1ll * B * res[mid].y
		 > 1ll * A * res[mid + 1].x + 1ll * B * res[mid + 1].y)
			lo = mid + 1;
		else hi = mid - 1;
	}
	return 1ll * A * res[lo].x + 1ll * B * res[lo].y;
}
posted @ 2025-10-03 21:14  Sktn0089  阅读(11)  评论(0)    收藏  举报