QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#488869#8509. Expanding STACKS!ucup-team1600#WA 0ms3824kbC++235.0kb2024-07-24 16:00:052024-07-24 16:00:07

Judging History

你现在查看的是最新测评结果

  • [2024-07-24 16:00:07]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3824kb
  • [2024-07-24 16:00:05]
  • 提交

answer

//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")

#include <bits/stdc++.h>

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T>
bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#ifdef KIVI
#define DEBUG for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define DEBUG while (false)
#define LOG(...)
#endif

const int max_n = -1, inf = 1000111222;

template<typename Edge>
class GraphIterator {
public:
    class OutgoingEdges {
    public:
        OutgoingEdges(const GraphIterator *g, int l, int r): g(g), l(l), r(r) {
        }

        const Edge* begin() const {
            if (l == r) {
                return 0;
            }
            return &g->prepared_edges[l];
        }

        const Edge* end() const {
            if (l == r) {
                return 0;
            }
            return &g->prepared_edges[r];
        }

    private:
        int l, r;
        const GraphIterator *g;
    };

    void clear() {
        prepared_edges.clear();
        edges.clear();
        start.clear();
        prepared = false;
    }

    void add_edge(int from, const Edge &e) {
        assert(!prepared && from >= 0);
        edges.push_back({from, e});
    }

    void prepare() {
        assert(!prepared);
        int n = 0;
        for (const auto &e : edges) {
            n = max(n, e.first);
        }
        n += 2;
        start.resize(n);
        for (const auto &e : edges) {
            ++start[e.first + 1];
        }
        for (int i = 1; i < n; ++i) {
            start[i] += start[i - 1];
        }
        prepared_edges.resize(edges.size() + 1);
        auto counter = start;
        for (const auto &e : edges) {
            prepared_edges[counter[e.first]++] = e.second;
        }
        prepared = true;
    }

    OutgoingEdges operator [] (int from) const {
        assert(prepared);
        if (from < 0 || from + 1 >= start.size()) {
            return {this, 0, 0};
        }
        return {this, start[from], start[from + 1]};
    }

private:
    vector<Edge> prepared_edges;
    vector<pair<int, Edge>> edges;
    vector<int> start;
    bool prepared = false;
};

class two_sat {
public:
    two_sat(int n): answer(n, -1) {
    }

    void add_or_clause(int x, bool valx, int y, bool valy) {
        x = x * 2 + valx;
        y = y * 2 + valy;
        g.add_edge(x ^ 1, y);
        g.add_edge(y ^ 1, x);
    }

    pair<bool, vector<int>> solve() {
        g.prepare();
        for (int i = 0; i < answer.size(); ++i) {
            if (answer[i] == -1) {
                lastv.clear();
                if (!dfs(2 * i)) {
                    for (int v : lastv) {
                        answer[v] = -1;
                    }
                    if (!dfs(2 * i + 1)) {
                        return {false, {}};
                    }
                }
            }
        }
        return {true, answer};
    }

private:
    bool dfs(int v) {
        lastv.push_back(v / 2);
        answer[v / 2] = v % 2;
        for (int to : g[v]) {
            if ((answer[to / 2] != -1 && answer[to / 2] != to % 2) || (answer[to / 2] == -1 && !dfs(to))) {
                return false;
            }
        }
        return true;
    }

    vector<int> answer, lastv;
    GraphIterator<int> g;
};

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n;
    cin >> n;
    vector <int> l(n, -1), r(n, -1);
    char c;
    int x;
    for (int i = 0; i < n + n; i++) {
        cin >> c >> x;
        --x;
        if (l[x] == -1) {
            l[x] = i;
        }
        else {
            r[x] = i;
        }
    }
    two_sat t(n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            int L = max(l[i], l[j]);
            int R = min(r[i], r[j]);
            if (R - L != min(r[i] - l[i], r[j] - l[j])) {
                t.add_or_clause(i, 0, j, 0);
                t.add_or_clause(i, 1, j, 1);
            }
        }
    }
    auto ans = t.solve();
    if (!ans.first) {
        cout << "*\n";
        return 0;
    }
    for (int i = 0; i < n; i++) {
        if (ans.second[i]) {
            cout << 'G';
        }
        else {
            cout << 'S';
        }
    }
    cout << '\n';
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3472kb

input:

2
+2 +1 -1 -2

output:

SS

result:

ok correct

Test #2:

score: 0
Accepted
time: 0ms
memory: 3812kb

input:

2
+1 +2 -1 -2

output:

SG

result:

ok correct

Test #3:

score: 0
Accepted
time: 0ms
memory: 3556kb

input:

3
+1 +2 +3 -1 -2 -3

output:

*

result:

ok correct

Test #4:

score: -100
Wrong Answer
time: 0ms
memory: 3824kb

input:

10
+3 -3 +4 -4 +6 +2 -2 -6 +7 -7 +5 -5 +10 +1 +9 +8 -8 -9 -1 -10

output:

*

result:

wrong answer team and jury output doesn't agree on whether there's an assignment