swjtucpc—嘉然今天吃什么
嘉然是枝江著名吃货,今天她沿着家背后的小巷子吃饭。小巷子长度为
L
L
L。她可以在任意时刻朝巷子正向走任意步(不能回头走)。在这条小巷子里有
n
n
n家餐馆,但令人无语的是,每家餐馆只在
t
i
t_i
ti?时刻营业。
嘉然并不担心这个问题,每家餐馆能在
t
i
t_i
ti?时刻将菜品送到她所在的位置。也就是说她能在
t
i
t_i
ti?时刻吃到所有在
t
i
t_i
ti?时刻营业的餐馆(作为知名吃货,她必须吃到这
n
n
n家餐馆的每一家)。
但等太久也会使她心烦,她的不满值
α
\alpha
α是餐馆的坐标
x
i
x_i
xi?和该时刻她的坐标
x
x
x的差的绝对值,即
α
=
∣
x
i
?
x
∣
\alpha =|x_i-x|
α=∣xi??x∣.
请设计程序使得嘉然的不满值之和最小。
题解:linkcuttree优化贪心 抄个板子就行,没写几行自己的代码。
通过代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int rd() {
int res = 0;
char ch = getchar();
while (!isdigit(ch)) {
ch = getchar();
}
while (isdigit(ch))
res = (res << 1) + (res << 3) + (ch ^ 48), ch = getchar();
return res;
}
const int N = 300010;
int h1[N], e[N << 2], ne[N << 2], idx;
int h2[N];
void add(int h[], int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
int sz[N], dfn[N];
int n, timestamp;
int son[N][2];
void dfs1(int u, int fa) {
sz[u] = 1;
dfn[u] = ++timestamp;
for (int i = h1[u]; i != -1; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
dfs1(v, u);
sz[u] += sz[v];
}
}
int len;
bool ok;
int q[N], tt;
int val[N << 2], tag[N << 2];
void pushdown(int u) {
if (tag[u] == 0) return;
tag[u << 1] += tag[u];
tag[u << 1 | 1] += tag[u];
val[u << 1] += tag[u];
val[u << 1 | 1] += tag[u];
tag[u] = 0;
}
int dep[N], f2[N], sz2[N];
void dfs3(int u) {
return;
sz2[u] = 1;
for (int i = h2[u]; i != -1; i = ne[i]) {
int v = e[i];
if (v == f2[u]) continue;
dep[v] = dep[u] + 1;
f2[v] = u;
dfs3(v);
if (sz2[u] == 1) son[u][0] = v;
son[u][1] = v;
sz2[u] += sz2[v];
}
}
void modify(int u, int l, int r, int L, int R, int v) {
if (L <= l && r <= R) {
val[u] += v;
tag[u] += v;
return;
}
pushdown(u);
int mid = l + r >> 1;
if (L <= mid) modify(u << 1, l, mid, L, R, v);
if (R > mid) modify(u << 1 | 1, mid + 1, r, L, R, v);
val[u] = max(val[u << 1], val[u << 1 | 1]);
}
void dfs2(int u) {
return;
if (ok) return;
int cur = dep[u];
if (cur >= len && (son[f2[u]][0] == u || u == 1)) {
int v = q[tt - len + 1];
modify(1, 1, n, dfn[v], dfn[v] + sz[v] - 1, -1);
}
q[++tt] = u;
modify(1, 1, n, dfn[u], dfn[u] + sz[u] - 1, 1);
if (cur + 1 >= len) {
ll tot = val[1];
if (tot <= 1) ok = 1;
}
for (int i = h2[u]; i != -1; i = ne[i]) {
int v = e[i];
if (v == f2[u]) continue;
dfs2(v);
}
--tt;
modify(1, 1, n, dfn[u], dfn[u] + sz[u] - 1, -1);
if (cur >= len && (son[f2[u]][1] == u || u == 1)) {
int v = q[tt - len + 1];
modify(1, 1, n, dfn[v], dfn[v] + sz[v] - 1, 1);
}
}
bool check(int x) {
len = x;
ok = 0;
tt = 0;
dfs2(1);
return ok;
}
int init(int ff) {
for (int i = 1; i <= n; i++) h1[i] = h2[i] = -1;
idx = timestamp = 0;
tt = 0;
for (int i = 1; i <= n; i++) dfn[i] = sz[i] = 0;
for (int i = 1; i <= n; i++) dep[i] = f2[i] = sz2[N] = 0;
for (int i = 1; i <= n; i++) son[i][0] = son[i][1] = 0;
int res = ff / 3;
return res;
}
struct node {
long long t, p;
} a[1000];
int main() {
int u, vv;
cin >> u >> vv;
for (int i = 1; i <= u; i++) {
scanf("%lld%lld", &a[i].t, &a[i].p);
}
long long ll = 1, rr = init(vv);
long long res = 0;
for (int i = ll; i <= rr; ++i) {
res += a[i].p;
}
cout << res << "\n";
return 0;
}
|