爆零求助
查看原帖
爆零求助
339858
winsun楼主2024/12/5 18:32

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;
}


2024/12/5 18:32
加载中...