제출 #37296

#제출 시각아이디문제언어결과실행 시간메모리
37296DoanPhuDucSailing Race (CEOI12_race)C++98
100 / 100
2356 ms11460 KiB
#include <bits/stdc++.h>

#define FOR(x, a, b) for (int x = a; x <= b; ++x)
#define FOD(x, a, b) for (int x = a; x >= b; --x)
#define REP(x, a, b) for (int x = a; x < b; ++x)
#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A, n) { cout << #A << " = "; FOR(_, 1, n) cout << A[_] << " "; cout << endl; }
#define PR0(A, n)  { cout << #A << " = "; REP(_, 0, n) cout << A[_] << " "; cout << endl; }
#define BitCount(x) __builtin_popcount(x)

using namespace std;

typedef long long LL;
typedef pair <int, int> II;

const int N = 5e2 + 10;
const int INF = 0x3f3f3f3f;

int n, request;
int CL1[N][N], CL2[N][N];
int dp[N][N][2], f[N][N][2], g[N][N][2];

bool e[N][N];
bool fre[N][N][2];

vector <int> adj[N], rev[N];

int O;

int CCW(int i, int j, int k) {
    if (i == k || j == k || i == j) return -1;
    if (i < j) {
        return (j < k && k < n) || (k < i);
    } else return (j < k && k < i);
}

bool CMP1(int x, int y) {
    return CCW(O, x, y);
}

bool CMP2(int x, int y) {
    return !CCW(O, x, y);
}

int DP(int l, int r, int k) {
    if (l == r) return dp[l][r][k] = 0;
    int &ans = dp[l][r][k];
    if (ans != -1) return ans;
    ans = 0;
    REP(i, 0, adj[l].size()) {
        int u = adj[l][i];
        if (CCW(l, u, r) == k) {
            ans = max(ans, 1 + DP(u, r, k));
            ans = max(ans, 1 + DP(u, l, k ^ 1));
        }
    }
    return ans;
}

int Compute(int l, int r, int k) {
    if (l == r) return 0;
    int &ans = f[l][r][k];
    if (ans != -1) return ans;
    ans = e[l][r] ? 1 : -INF;
    REP(i, 0, adj[l].size()) {
        int u = adj[l][i];
        if (CCW(l, r, u) == (k ^ 1)) {
            ans = max(ans, 1 + Compute(u, r, k));
        }
    }
    return ans;
}

void Init() {
    memset(CL1, -1, sizeof CL1);
    memset(CL2, -1, sizeof CL2);
    REP(i, 0, n) {
        O = i;
        sort(rev[i].begin(), rev[i].end(), CMP1);
        int p = 0;
        for (int j = (i + 1) % n; j != i; j = (j + 1) % n) {
            while (p < rev[i].size() && CCW(i, j, rev[i][p]) != 1) ++p;
            if (p < rev[i].size()) CL1[i][j] = rev[i][p];
        }
        sort(rev[i].begin(), rev[i].end(), CMP2);
            p = 0;
        for (int j = (i - 1 + n) % n; j != i; j = (j - 1 + n) % n) {
            while (p < rev[i].size() && CCW(i, j, rev[i][p]) != 0) ++p;
            if (p < rev[i].size()) CL2[i][j] = rev[i][p];
        }

    }
}

int main() {
    #ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif // LOCAL
    scanf("%d%d", &n, &request);
    REP(u, 0, n) {
        int v;
        while (scanf("%d", &v) == 1) {
            if (v == 0) break;
            assert(v - 1 != u);
            e[u][v - 1] = true;
            adj[u].push_back(v - 1);
            rev[v - 1].push_back(u);
        }
    }
    Init();
    memset(dp, -1, sizeof dp);
    int ans = 0, num = 0;
    REP(u, 0, n) {
        REP(k, 0, adj[u].size()) {
            int v = adj[u][k];
            int can = 1 + DP(v, u, 0);
            if (can > ans) {
                ans = can;
                num = u;
            }
                can = 1 + DP(v, u, 1);
            if (can > ans) {
                ans = can;
                num = u;
            }
        }
    }
    if (request == 0) {
        printf("%d\n%d", ans, num + 1);
        return 0;
    }
    memset(f, -1, sizeof f);
    REP(i, 0, n) {
        for (int j = (i + 1) % n; j != i; j = (j + 1) % n) {
            int x = Compute(i, j, 1); if (x == 0) continue;
            int k = CL1[i][j]; if (k == -1) continue;
            REP(p, 0, adj[j].size()) {
                int v = adj[j][p];
                if (CCW(j, k, v) == 1 && CCW(v, i, j) == 1) {
                    int can = 2 + x + max(DP(v, k, 0), DP(v, i, 1));
                    if (can > ans) {
                        ans = can;
                        num = k;
                    }
                }
            }
        }
        for (int j = (i - 1 + n) % n; j != i; j = (j - 1 + n) % n) {
            int x = Compute(i, j, 0); if (x == 0) continue;
            int k = CL2[i][j]; if (k == -1) continue;
            REP(p, 0, adj[j].size()) {
                int v = adj[j][p];
                if (CCW(j, k, v) == 0 && CCW(v, i, j) == 0) {
                    int can = 2 + x + max(DP(v, k, 1), DP(v, i, 0));
                    if (can > ans) {
                        ans = can;
                        num = k;
                    }
                }
            }
        }
    }
    printf("%d\n%d", ans, num + 1);
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

race.cpp: In function 'int DP(int, int, int)':
race.cpp:5:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define REP(x, a, b) for (int x = a; x < b; ++x)
                                        ^
race.cpp:50:5: note: in expansion of macro 'REP'
     REP(i, 0, adj[l].size()) {
     ^
race.cpp: In function 'int Compute(int, int, int)':
race.cpp:5:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define REP(x, a, b) for (int x = a; x < b; ++x)
                                        ^
race.cpp:65:5: note: in expansion of macro 'REP'
     REP(i, 0, adj[l].size()) {
     ^
race.cpp: In function 'void Init()':
race.cpp:82:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (p < rev[i].size() && CCW(i, j, rev[i][p]) != 1) ++p;
                      ^
race.cpp:83:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             if (p < rev[i].size()) CL1[i][j] = rev[i][p];
                   ^
race.cpp:88:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (p < rev[i].size() && CCW(i, j, rev[i][p]) != 0) ++p;
                      ^
race.cpp:89:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             if (p < rev[i].size()) CL2[i][j] = rev[i][p];
                   ^
race.cpp: In function 'int main()':
race.cpp:5:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define REP(x, a, b) for (int x = a; x < b; ++x)
                                        ^
race.cpp:115:9: note: in expansion of macro 'REP'
         REP(k, 0, adj[u].size()) {
         ^
race.cpp:5:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define REP(x, a, b) for (int x = a; x < b; ++x)
                                        ^
race.cpp:138:13: note: in expansion of macro 'REP'
             REP(p, 0, adj[j].size()) {
             ^
race.cpp:5:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define REP(x, a, b) for (int x = a; x < b; ++x)
                                        ^
race.cpp:152:13: note: in expansion of macro 'REP'
             REP(p, 0, adj[j].size()) {
             ^
race.cpp:100:32: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d", &n, &request);
                                ^
#Verdict Execution timeMemoryGrader output
Fetching results...