Luogu Wrong Answer 爆零,且交到校 OJ 上时,校 OJ 的 SPJ RE 了。
本人已调试一下午,且使用自己编写的 checker 并未发现问题。
也许是否漏判情况?
// 爆零代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>
#include <utility>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef __int128 LLL;
template <typename Tp> inline void read(Tp& x) {
char ch; bool op = 0; x = 0;
do ch = getchar(), op |= ch == '-'; while (ch < '0' || ch > '9');
do x = (x<<3)+(x<<1)+(ch&15), ch = getchar(); while (ch >= '0' && ch <= '9');
if (op) x = -x;
}
template <typename Tp> inline void write(Tp x, const char ch = '\n') {
static int arr[50]; int tp = 0;
if (x < 0) putchar('-'), x = -x;
do arr[++tp] = x % 10, x /= 10; while (x);
for (; tp; --tp) putchar(arr[tp]|48); putchar(ch);
}
bool Mst;
inline void link(int x, int y) {
if (!~x || !~y || y - x == 1) return;
write(x, ' '), write(y);
}
inline int calcV(int x) { return x * (x+1) / 2; }
const int MAXN = 2005;
int n, m;
int f[20][MAXN], ffr[20][MAXN], g[20][MAXN], gfr[20][MAXN];
inline int calcW(int tot, int i, int k) {
int q = tot / i, r = tot % i;
return (f[k][q] + q * 2) * (i - r) + (f[k][q+1] + (q+1)*2) * r;
}
void solveF(int, int, vector<int>);
void solveG(int, int, vector<int>);
bool Med;
int main() {
#ifndef ONLINE_JUDGE
assert(freopen("lg8984.in", "r", stdin));
assert(freopen("lg8984.out", "w", stdout));
fprintf(stderr, "%.3lfMiB\n", (&Mst - &Med) / 1048576.);
#endif
read(n), read(m);
memset(f, 0x3f, sizeof(f));
memset(g, 0x3f, sizeof(g));
for (int x = 0; x <= n; ++x) f[1][x] = x * (x-1) / 2;
for (int k = 2; k <= m; ++k) {
f[k][0] = 0;
f[k][1] = g[k][1] = 0;
for (int x = 2; x <= n; ++x) {
for (int i = 1, cur; i < x; ++i) {
cur = f[k-2][i+1] + calcW(x-i-1, i, k);
if (cur < g[k][x]) g[k][x] = cur, gfr[k][x] = i;
cur = g[k][x-i] + f[k][i>>1] + f[k][i-(i>>1)] + i;
if (cur < f[k][x]) f[k][x] = cur, ffr[k][x] = i;
}
}
}
write(f[m][n] - n + 1);
vector<int> arr;
for (int i = 0; i < n; ++i) arr.emplace_back(i);
solveF(n, m, arr);
return 0;
}
void solveF(int x, int k, vector<int> arr) {
if (x <= 1) return;
assert(x == (int)arr.size());
if (k == 1) {
for (int i = 0; i < x; ++i)
for (int j = i+1; j < x; ++j)
link(arr[i], arr[j]);
return;
}
int t = ffr[k][x], p = t >> 1, q = t - p;
vector<int> lv, mv, rv;
for (int i = 0; i < p; ++i) lv.emplace_back(arr[i]);
for (int i = p; i < x-q; ++i) mv.emplace_back(arr[i]);
for (int i = x-q; i < x; ++i) rv.emplace_back(arr[i]);
solveF(p, k, lv);
for (int u : lv) link(u, arr[p]);
solveF(q, k, rv);
for (int u : rv) link(arr[x-q-1], u);
assert(arr[p] < n && arr[p] >= 0 && arr[x-q-1] < n && arr[x-q-1] >= 0);
solveG(x-t, k, mv);
}
void solveG(int x, int k, vector<int> arr) {
if (x <= 1) return;
assert(x == (int)arr.size());
int t = gfr[k][x];
int tot = x - t - 1, q = tot / t, r = tot % t;
vector<int> res = {arr[0]}, cur;
int tar = (r ? (--r, q+1) : q) + 1;
for (int i = 1; i < x; ++i) {
if (i == tar) {
solveF(cur.size(), k, cur);
int a = *--res.end(), b = arr[i];
for (int u : cur) link(a, u), link(u, b);
assert(b < n);
res.emplace_back(b);
cur.clear();
tar = i + (r ? (--r, q+1) : q) + 1;
} else {
cur.emplace_back(arr[i]);
}
}
assert(cur.empty());
solveF(t+1, k-2, res);
}
// 自制 checker
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>
#include <utility>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef __int128 LLL;
template <typename Tp> inline void read(Tp& x) {
char ch; bool op = 0; x = 0;
do ch = getchar(), op |= ch == '-'; while (ch < '0' || ch > '9');
do x = (x<<3)+(x<<1)+(ch&15), ch = getchar(); while (ch >= '0' && ch <= '9');
if (op) x = -x;
}
template <typename Tp> inline void write(Tp x, const char ch = '\n') {
static int arr[50]; int tp = 0;
if (x < 0) putchar('-'), x = -x;
do arr[++tp] = x % 10, x /= 10; while (x);
for (; tp; --tp) putchar(arr[tp]|48); putchar(ch);
}
bool Mst;
int n, m;
const int MAXN = 2e3+5, MAXM = 1e5+5;
int head[MAXN], ver[MAXM], nxt[MAXM], tot;
void add(int x, int y) {
ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}
int dis[MAXN];
bool vis[MAXN];
bool conn[MAXN][MAXN];
bool bfs(int S) {
memset(vis, 0, sizeof(vis));
queue<int> q;
q.emplace(S);
vis[S] = 1, dis[S] = 0;
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = head[x]; i; i = nxt[i]) {
int y = ver[i];
if (!vis[y]) q.emplace(y), dis[y] = dis[x] + 1, vis[y] = 1;
}
}
for (int i = S+1; i <= n; ++i) if (dis[i] > m) return 0;
return 1;
}
bool Med;
int main() {
#ifndef ONLINE_JUDGE
assert(freopen("lg8984.in", "r", stdin));
read(n), read(m);
fclose(stdin);
assert(freopen("lg8984.out", "r", stdin));
fprintf(stderr, "%.3lfMiB\n", (&Mst - &Med) / 1048576.);
#endif
int tot; read(tot);
vector<pair<int, int> > edge;
for (int i = 1; i <= tot; ++i) {
int x, y; read(x), read(y), ++x, ++y;
add(x, y);
conn[x][y] = 1;
edge.emplace_back(x, y);
}
for (int i = 1; i < n; ++i) add(i, i+1), conn[i][i+1] = 1;
bool f = 1;
for (int i = 1; i < n; ++i) f &= bfs(i);
for (auto e : edge) {
int x = e.fi, y = e.se;
bool cur = 0;
for (int k = x + 1; k < y; ++k) cur |= conn[x][k] & conn[k][y];
f &= cur;
}
write(f);
return 0;
}