QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#91831#5504. Flower GardenDenisovTL 0ms0kbC++2010.0kb2023-03-29 17:44:132023-03-29 17:44:17

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-29 17:44:17]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2023-03-29 17:44:13]
  • 提交

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>
inline bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

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

#ifdef LOCAL
#define D 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 D while (false)
#define LOG(...)
#endif // LOCAL

const int max_n = 5e5 + 18 * 1e5 * 4, 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 pair<int, Edge>* begin() const {
            if (l == r) {
                return 0;
            }
            return &g->edges[l];
        }

        const pair<int, Edge>* end() const {
            if (l == r) {
                return 0;
            }
            return &g->edges[r];
        }

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

    void 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];
        }
        auto counter = start;
        for (int i = 0; i < (int)edges.size(); ) {
            if (start[edges[i].first] <= i && i < counter[edges[i].first]) {
                i = counter[edges[i].first];
                continue;
            }
            swap(edges[i], edges[counter[edges[i].first]]);

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

    vector<pair<int, Edge>> edges;
    vector<int> start;
    bool prepared = false;
};
GraphIterator<int> g, gr;

pii e[max_n];
pii e1[max_n];
int n, num = 0;


vector <int> t, t1;

inline void upd (int v, int tl, int tr, int l, int r, int id, bool from) {
    if (l > r) return;
    if (tl == l && tr == r) {
        if (from) {
            g.add_edge(id, t1[v]);
            //e[num++] = {id, t1[v]};
        }
        else {
            g.add_edge(t[v], id);
            //e[num++] = {t[v], id};
        }
        return;
    }
    int tm = (tl + tr) >> 1;
    upd(v << 1, tl, tm, l, min(r, tm), id, from);
    upd(v << 1 | 1, tm + 1, tr, max(tm + 1, l), r, id, from);
}
int mx;


inline int build (int v, int tl, int tr) {
    umax(mx, 3 * n + v + 1);
    t[v] = 3 * n + v;
    if (tl == tr) {
        g.add_edge(tr, 3 * n + v);
        //e[num++] = {tr, 3 * n + v};
        return 3 * n + v;
    }
    int tm = (tl + tr) >> 1;
    int L = build(v << 1, tl, tm);
    int R = build(v << 1 | 1, tm + 1, tr);
    g.add_edge(L, 3 * n + v);
    g.add_edge(R, 3 * n + v);
    //e[num++] = {L, 3 * n + v};
    //e[num++] = {R, 3 * n + v};
    return 3 * n + v;
}

inline int build1 (int v, int tl, int tr) {
    t1[v] = mx++;
    if (tl == tr) {
        g.add_edge(t1[v], tr);
        //e[num++] = {t1[v], tr};
        return t1[v];
    }
    int tm = (tl + tr) >> 1;
    int L = build1(v << 1, tl, tm);
    int R = build1(v << 1 | 1, tm + 1, tr);
    g.add_edge(t1[v], L);
    g.add_edge(t1[v], R);
    //e[num++] = {t1[v],L};
    //e[num++] = {t1[v],R};
    return t1[v];
}

vector <int> used, order, cl, w, p, p1;

inline void dfs (int v) {
    used[v] = 1;
    auto cur = g[v];
    for (int i = cur.l; i < cur.r; i++) {
        int to = cur.g->edges[i].second;
        //if (e[i].first != v) break;
        //int to = e[i].second;
        if (!used[to]) {
            dfs(to);
        }
    }
    order.pb(v);
}

inline void dfs1 (int v, int c) {
    used[v] = 2;
    cl[v] = c;
    w[c] += v < 3 * n;
    auto cur = gr[v];
    for (int i = cur.l; i < cur.r; i++) {
        int to = cur.g->edges[i].second;
        //if (e1[i].first != v) break;
        //int to = e1[i].second;
        if (used[to] == 1) {
            dfs1(to, c);
        }
    }
}


vector <int> ans;

inline void color (int v) {
    ans[v] = 1;
    auto cur = g[v];
    for (int i = cur.l; i < cur.r; i++) {
        int to = cur.g->edges[i].second;
        //if (e[i].first != v) break;
        //int to = e[i].second;
        if (!ans[to]) {
            color(to);
        }
    }
}

inline void color1 (int v) {
    ans[v] = 0;
    auto cur = gr[v];
    for (int i = cur.l; i < cur.r; i++) {
        int to = cur.g->edges[i].second;
        //if (e[i].first != v) break;
        //int to = e[i].second;
        if (ans[to]) {
            color1(to);
        }
    }
}

inline void test_case () {
    ans.clear();
    p.clear();
    p1.clear();
    t.clear();
    t1.clear();
    cl.clear();
    w.clear();
    used.clear();
    g.clear();
    gr.clear();
    order.clear();
    num = 0;
    mx = 0;
    int q;
    cin >> n >> q;
    t.resize(3 * 4 * n);
    t1.resize(3 * 4 * n);
    build(1, 0, 3 * n - 1);
    build1(1, 0, 3 * n - 1);
    for (int i = 0, a, b, c, d; i < q; i++) {
        cin >> a >> b >> c >> d;
        --a, --b, --c, --d;
        int cur = mx;
        upd(1, 0, 3 * n - 1, c, d, cur, false);
        upd(1, 0, 3 * n - 1, a, b, cur, true);
        ++mx;
    }
    //LOG("here");
    int N = mx;
    for (auto &i : g.edges) {
        gr.add_edge(i.second, i.first);
    }
    g.prepare();
    gr.prepare();
    /*for (int i = 0; i < num; i++) {
        e1[i] = {e[i].second, e[i].first};
    }
    sort(e, e + num);
    sort(e1, e1 + num);
    p.resize(N);
    p1.resize(N);
    for (int i = 0, j = 0; i < N; i++) {
        while (j < num && e[j].first < i) {
            ++j;
        }
        p[i] = j;
    }
    for (int i = 0, j = 0; i < N; i++) {
        while (j < num && e1[j].first < i) {
            ++j;
        }
        p1[i] = j;
    }*/
    used.resize(N);
    for (int i = 0; i < N; i++) {
        if (!used[i]) {
            dfs(i);
        }
    }
    reverse(all(order));
    w.resize(N);
    cl.resize(N);
    int cmp = 0;
    for (int i : order) {
        if (used[i] == 1) {
            dfs1(i, cmp);
            ++cmp;
        }
    }
    for (int i = 0; i < cmp; i++) {
        if (w[i] > 2 * n) {
            cout << "NIE\n";
            return;
        }
    }
    /*for (int it = 0; it < num; it++) {
        pii i = e[it];
        e[it] = {cl[i.first], cl[i.second]};
        i = e1[it];
        e1[it] = {cl[i.first], cl[i.second]};
    }
    sort(e, e + num);
    sort(e1, e1 + num);
    for (int i = 0, j = 0; i < cmp; i++) {
        while (j < num && e[j].first < i) {
            ++j;
        }
        p[i] = j;
    }
    for (int i = 0, j = 0; i < cmp; i++) {
        while (j < num && e1[j].first < i) {
            ++j;
        }
        p1[i] = j;
    }*/
    g.clear();
    for (auto &i : gr.edges) {
        g.add_edge(cl[i.second], cl[i.first]);
    }
    gr.clear();
    for (auto &i : g.edges) {
        gr.add_edge(i.second, i.first);
    }
    g.prepare();
    gr.prepare();
    ans.resize(cmp);
    /// 1 - rose
    /// 0 - violet
    for (int i = 0; i < cmp; i++) {
        if (w[i] > n) {
            int cnt = 0;
            color(i);
            string answer(3 * n, 'F');
            for (int j = 0; j < 3 * n; j++) {
                if (ans[cl[j]]) {
                    answer[j] = 'R';
                    ++cnt;
                }
            }
            if (cnt >= n && cnt <= 2 * n) {
                cout << "TAK\n";
                cout << answer << '\n';
                return;
            }
            cnt = 0;
            ans.assign(cmp, 1);
            color1(i);
            answer = string(3 * n, 'R');
            for (int j = 0; j < 3 * n; j++) {
                if (!ans[cl[j]]) {
                    ++cnt;
                    answer[j] = 'F';
                }
            }
            if (!(cnt >= n && cnt <= 2 * n)) {
                cout << "NIE\n";
                return;
            }
            cout << "TAK\n";
            cout << answer << '\n';
            return;
        }
    }
    order.clear();
    used.clear();
    used.resize(cmp);
    for (int i = 0; i < cmp; i++) {
        if (!used[i]) {
            dfs(i);
        }
    }
    int s = 0;
    for (int v : order) {
        s += w[v];
        ans[v] = 1;
        if (s >= n) {
            assert(s <= 2 * n);
            break;
        }
    }
    assert(s >= n);
    string answer(3 * n, 'F');
    int cnt = 0;
    for (int i = 0; i < 3 * n; i++) {
        if (ans[cl[i]]) {
            ++cnt;
            answer[i] = 'R';
        }
    }
    assert(cnt >= n && cnt <= 2 * n);
    cout << "TAK\n";
    cout << answer << '\n';
}

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

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = 1;
    cin >> t;
    for (int test = 1; test <= t; test++) {
        test_case();
    }
}

詳細信息

Test #1:

score: 0
Time Limit Exceeded

input:

2
1 3
1 1 2 2
1 2 3 3
1 1 3 3
1 3
1 1 2 2
2 2 3 3
3 3 1 1

output:


result: