답안 #746753

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
746753 2023-05-23T03:53:12 Z Olympia Radio (COCI22_radio) C++17
10 / 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++) {
        for (int j = 0; j < N; j++) {
            act[j] = false;
        }
        SegmentTree st(N/i + 1);
        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] + 1)/i, 1);
                    } else {
                        st.update((q[0] + 1)/i, 0);
                    }
                    act[q[0]] = not act[q[0]];
                }
            } else {
                int l = q[0] + 1, r = q[1] + 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:145:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  145 |         for (int j = 0; j < queries.size(); j++) {
      |                         ~~^~~~~~~~~~~~~~~~
Main.cpp:170:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  170 |     for (int i = 0; i < queries.size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~~
Main.cpp:206:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  206 |     for (int i = 0; i < queries.size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 1 ms 212 KB Output is correct
6 Correct 0 ms 212 KB Output is correct
7 Correct 1 ms 212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1238 ms 14796 KB Output is correct
2 Execution timed out 1582 ms 13176 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 1 ms 212 KB Output is correct
5 Correct 1 ms 212 KB Output is correct
6 Correct 0 ms 212 KB Output is correct
7 Correct 1 ms 212 KB Output is correct
8 Correct 1238 ms 14796 KB Output is correct
9 Execution timed out 1582 ms 13176 KB Time limit exceeded
10 Halted 0 ms 0 KB -