답안 #746751

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
746751 2023-05-23T03:50:19 Z Olympia Radio (COCI22_radio) C++17
0 / 110
1500 ms 14796 KB
#include <vector>
#include <iostream>
#include <cassert>
#include <cmath>
#include <map>
#include <set>
using namespace std;
struct SegmentTree {
    vector<int> vec;
    const int id = 0;
    int merge (int x, int y) {
        return x + y;
    }
    void update (int x, int y) {
        x += (int)vec.size()/2 - 1;
        vec[x] = y;
        while (x != 0) {
            x = (x - 1)/2;
            vec[x] = merge(vec[2 * x + 1], vec[2 * x + 2]);
        }
    }
    int query (int dum, int tl, int tr, int l, int r) {
        if (tl >= l and tr <= r) {
            return vec[dum];
        }
        if (tl > r or tr < l) {
            return id;
        }
        return merge(query(2 * dum + 1, tl, (tl + tr)/2, l, r), query(2 * dum + 2, (tl + tr)/2 + 1, tr, l, r));
    }
    int query (int l, int r) {
        return query(0, 0, (int)vec.size()/2 - 1, l, r);
    }
    SegmentTree (int n) {
        n = (1 << ((int)log2(n) + 1));
        vec.assign(2 * n, 0);
    }
};

struct SegmentTreeMin {
    vector<int> vec;
    const int id = (int)1e9;
    int merge (int x, int y) {
        return min(x, y);
    }
    void update (int x, int y) {
        x += (int)vec.size()/2 - 1;
        vec[x] = y;
        while (x != 0) {
            x = (x - 1)/2;
            vec[x] = merge(vec[2 * x + 1], vec[2 * x + 2]);
        }
    }
    int query (int dum, int tl, int tr, int l, int r) {
        if (tl >= l and tr <= r) {
            return vec[dum];
        }
        if (tl > r or tr < l) {
            return id;
        }
        return merge(query(2 * dum + 1, tl, (tl + tr)/2, l, r), query(2 * dum + 2, (tl + tr)/2 + 1, tr, l, r));
    }
    int query (int l, int r) {
        return query(0, 0, (int)vec.size()/2 - 1, l, r);
    }
    SegmentTreeMin (int n) {
        n = (1 << ((int)log2(n) + 1));
        vec.assign(2 * n, id);
    }
};

struct SegmentTreeMax {
    vector<int> vec;
    const int id = -(int)1e9;
    int merge (int x, int y) {
        return max(x, y);
    }
    void update (int x, int y) {
        x += (int)vec.size()/2 - 1;
        vec[x] = y;
        while (x != 0) {
            x = (x - 1)/2;
            vec[x] = merge(vec[2 * x + 1], vec[2 * x + 2]);
        }
    }
    int query (int dum, int tl, int tr, int l, int r) {
        if (tl >= l and tr <= r) {
            return vec[dum];
        }
        if (tl > r or tr < l) {
            return id;
        }
        return merge(query(2 * dum + 1, tl, (tl + tr)/2, l, r), query(2 * dum + 2, (tl + tr)/2 + 1, tr, l, r));
    }
    int query (int l, int r) {
        return query(0, 0, (int)vec.size()/2 - 1, l, r);
    }
    SegmentTreeMax (int n) {
        n = (1 << ((int)log2(n) + 1));
        vec.assign(2 * n, id);
    }
};

int main () {
    //freopen("grass.out", "r", stdin);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int N, Q;
    cin >> N >> Q;
    vector<vector<int>> queries;
    vector<bool> ans;
    ans.assign(Q, false);
    vector<int> factors(N + 1);
    vector<bool> isPrime(N + 1);
    isPrime.assign(N + 1, true);
    factors[1] = 1;
    for (int i = 2; i <= N; i++) {
        if (not isPrime[i]) {
            continue;
        }
        for (int j = i; j <= N; j += i) {
            factors[j] = i;
            isPrime[j] = false;
        }
    }
    while (Q--) {
        char c;
        cin >> c;
        if (c == 'C') {
            int x, y;
            cin >> x >> y;
            queries.push_back({--x, --y});
        } else {
            int x; cin >> x;
            queries.push_back({--x});
        }
    }
    //cout << "OKAY1\n";
    vector<bool> act(N);
    for (int i = 2; i * i <= N; i++) {
        //cout << i << '\n';
        for (int j = 0; j < N; j++) {
            act[j] = false;
        }
        SegmentTree st(N/i);
        for (int j = 0; j < queries.size(); j++) {
            auto q = queries[j];
            if (q.size() == 1) {
                if ((q[0] + 1) % i == 0) {
                    if (!act[q[0]]) {
                        st.update(q[0]/i, 1);
                    } else {
                        st.update(q[0]/i, 0);
                    }
                    act[q[0]] = not act[q[0]];
                }
            } else {
                int l = q[0], r = q[1];
                if (st.query((l + i + 1)/i, r/i) >= 2) {
                    ans[j] = true;
                }
            }
        }
    }
    //cout << "OKAY\n";
    //array of values[]
    //check if it is all discint
    SegmentTreeMin next_oc(N + 1);
    set<int> oc[N];
    act.assign(N, false);
    for (int i = 0; i < queries.size(); i++) {
        auto q = queries[i];
        if (q.size() == 1) {
            if ((q[0] + 1) * (q[0] + 1) < N) {
                continue;
            }
            int x = q[0];
            if (act[x]) {
                oc[factors[x + 1]].erase(q[0]);
                next_oc.update(x, next_oc.id);
                auto it = oc[factors[x + 1]].lower_bound(q[0]);
                if (it != oc[factors[x + 1]].begin()) {
                    --it;
                    next_oc.update(*it, next_oc.id);
                }
            } else {
                oc[factors[x + 1]].insert(q[0]);
                auto it = oc[factors[x + 1]].upper_bound(q[0]);
                if (it != oc[factors[x + 1]].end()) {
                    next_oc.update(x, *it);
                }
                it = oc[factors[x + 1]].lower_bound(q[0]);
                if (it != oc[factors[x + 1]].begin()) {
                    --it;
                    next_oc.update(*it, x);
                }
            }
            act[q[0]] = not act[q[0]];
        } else {
            int l = q[0], r = q[1];
            int res = next_oc.query(l, r);
            if (res <= r) {
                ans[i] = 1;
            }
        }
    }
    for (int i = 0; i < queries.size(); i++) {
        if (queries[i].size() == 2) {
            cout << (ans[i] ? "DA" : "NE") << '\n';
        }
    }
}

Compilation message

Main.cpp: In function 'int main()':
Main.cpp:146:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  146 |         for (int j = 0; j < queries.size(); j++) {
      |                         ~~^~~~~~~~~~~~~~~~
Main.cpp:171:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  171 |     for (int i = 0; i < queries.size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~~
Main.cpp:207:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  207 |     for (int i = 0; i < queries.size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1266 ms 14796 KB Output is correct
2 Execution timed out 1576 ms 13184 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -