답안 #197111

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
197111 2020-01-18T20:45:26 Z Anai 가로등 (APIO19_street_lamps) C++14
20 / 100
5000 ms 524292 KB
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;

using pii = pair<int, int>;

const int N = 3e5 + 5;

struct Iv {
    int st, dr, val;
};

struct Query {
    int st, dr, idx;
};

struct Update {
    int pos, idx;
};

class SegTree {
public:
    struct Nod {
        int st, dr;
        int lazy, sum;
    };

    vector<Nod> acc;
    int pom[N * 4];
    int ql, qr, qval, qh;

    int make_nod() {
        acc.push_back({0, 0, 0, 0});
        return acc.size() - 1;
    }

    void prop(int nod, int st, int dr) {
        if (acc[nod].st == 0) {
            int t = make_nod();
            acc[nod].st = t;
        }
        if (acc[nod].dr == 0) {
            int t = make_nod();
            acc[nod].dr = t;
        }
        acc[nod].sum+= acc[nod].lazy * (dr - st + 1);
        acc[acc[nod].st].lazy+= acc[nod].lazy;
        acc[acc[nod].dr].lazy+= acc[nod].lazy;
        acc[nod].lazy = 0;
    }

    int eval(int nod, int st, int dr) {
        return acc[nod].sum + (dr - st + 1) * acc[nod].lazy;
    }

    int update_deep(int nod, int st, int dr) {
        assert(0 <= st && st <= dr && dr <= N);
        if (nod == 0) nod = make_nod();
        if (ql <= st && dr <= qr) {
            acc[nod].lazy+= qval;
            return nod;
        }
        int mid = (st + dr) / 2;
        prop(nod, st, dr);
        if (ql <= mid) {
            int t = update_deep(acc[nod].st, st, mid); 
            acc[nod].st = t;
        }
        if (mid < qr) {
            int t = update_deep(acc[nod].dr, mid + 1, dr); 
            acc[nod].dr = t;
        }
        acc[nod].lazy = 0;
        acc[nod].sum = eval(acc[nod].st, st, mid) + eval(acc[nod].dr, mid + 1, dr);
        return nod;
    }

    void update_shallow(int nod, int st, int dr) {
        assert(0 <= st && st <= dr && dr <= N);
        pom[nod] = update_deep(pom[nod], 0, N);
        if (st == dr)
            return;
        int mid = (st + dr) / 2;
        if (qh <= mid)
            update_shallow(2 * nod, st, mid);
        else
            update_shallow(2 * nod + 1, mid + 1, dr);
    }

    pii query_deep(int nod, int st, int dr) {
        assert(0 <= st && st <= dr && dr <= N);
        if (nod == 0) nod = make_nod();
        if (ql <= st && dr <= qr)
            return pii(nod, eval(nod, st, dr));

        int mid = (st + dr) / 2, ans = 0;
        prop(nod, st, dr);
        if (ql <= mid) {
            pii ret = query_deep(acc[nod].st, st, mid);
            acc[nod].st = ret.x;
            ans+= ret.y;
        }
        if (mid < qr) {
            pii ret = query_deep(acc[nod].dr, mid + 1, dr);
            acc[nod].dr = ret.x;
            ans+= ret.y;
        }
        return pii(nod, ans);
    }

    int query_shallow(int nod, int st, int dr) {
        assert(0 <= st && st <= dr && dr <= N);
        if (st > qh)
            return 0;
        if (dr <= qh) {
            pii ret = query_deep(pom[nod], 0, N);
            pom[nod] = ret.x;
            return ret.y;
        }
        int ans = 0, mid = (st + dr) / 2;
        ans+= query_shallow(2 * nod, st, mid);
        ans+= query_shallow(2 * nod + 1, mid + 1, dr);
        return ans;
    }

public:
    void update(int st, int dr, int h, int val) {
        ql = st, qr = dr, qh = h, qval = val;
        update_shallow(1, 0, N);
    }

    int query(int st, int dr, int h) {
        ql = st, qr = dr, qh = h;
        return query_shallow(1, 0, N);
    }

    SegTree() {
        acc.reserve(N * 16);
        acc.push_back({0, 0, 0, 0});
    }
};

inline bool operator < (const Iv &a, const Iv &b) { return a.st < b.st; }

vector<int> upd;
char str[N];
int ans[N];

set<Iv> s;
vector<Query> qs;
vector<Update> ups;
SegTree magic;
int n, q;

static void apply(int newh, int st, int dr) {
    if (st > dr)
        return;
    auto it = prev(s.upper_bound(Iv {st, st, st}));
    Iv fst, lst;
    fst = lst = *it;
    for (; it != end(s) && it->st <= dr;) {
        lst = *it;
        auto inc = next(it);
        magic.update(it->st, it->dr, it->val, -1);
        s.erase(it);
        it = inc;
    }

    magic.update(st, dr, newh, 1);
    s.insert(Iv {st, dr, newh});
    if (fst.st <= st - 1) {
        magic.update(fst.st, st - 1, fst.val, 1);
        s.insert(Iv {fst.st, st - 1, fst.val});
    }
    if (dr + 1 <= lst.dr) {
        magic.update(dr + 1, lst.dr, lst.val, 1);
        s.insert(Iv {dr + 1, lst.dr, lst.val});
    }
}

int main() {
#ifdef HOME
    freopen("streetlights.in", "r", stdin);
    freopen("streetlights.out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int ptru(0), ptrq(0);

    cin >> n >> q >> (str + 1);
    upd.reserve(2 * N);
    qs.reserve(N);
    for (int i = 1; i <= q; ++i) {
        string op;
        cin >> op;
        if (op == "query") {
            int l, r;
            cin >> l >> r;
            qs.push_back({l, r - 1, i});
        }
        else {
            int pos;
            cin >> pos;
            ups.push_back({pos, i});
        }
    }
    for (int i = 1; i <= n; ++i)
        if (str[i] == '0')
            ups.push_back({i, 0});

    sort(begin(qs), end(qs), [&](const Query &a, const Query &b) { return pii(a.dr, a.idx) < pii(b.dr, b.idx); });
    sort(begin(ups), end(ups), [&](const Update &a, const Update &b) { return pii(a.pos, a.idx) < pii(b.pos, b.idx); });

    s.insert(Iv {0, q, 1});
    magic.update(0, q, 1, 1);

    for (int i = 1; i <= n; ++i) {
        vector<pii> upd;
        int lst_tid = -1; 

        while (ptru < int(ups.size()) && ups[ptru].pos <= i) {
            upd.emplace_back(lst_tid + 1, ups[ptru].idx);
            lst_tid = ups[ptru].idx;
            ptru+= 1;
        }
        upd.emplace_back(lst_tid + 1, q);

        for (int j = 1; j < int(upd.size()); j+= 2) {
            apply(i + 1, upd[j].x, upd[j].y);
        }


        while (ptrq < int(qs.size()) && qs[ptrq].dr <= i) {
            ans[qs[ptrq].idx] = magic.query(1, qs[ptrq].idx, qs[ptrq].st);
            ptrq+= 1;
        }
    }

    sort(begin(qs), end(qs), [&](const Query &a, const Query &b) {
        return a.idx < b.idx; });

    for (auto i: qs)
        cout << ans[i.idx] << '\n';

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 432 KB Output is correct
2 Correct 3 ms 504 KB Output is correct
3 Correct 1 ms 504 KB Output is correct
4 Correct 5 ms 632 KB Output is correct
5 Correct 3 ms 632 KB Output is correct
6 Correct 5 ms 632 KB Output is correct
7 Correct 2 ms 504 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5032 ms 305404 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 3832 KB Output is correct
2 Correct 35 ms 3364 KB Output is correct
3 Correct 24 ms 2680 KB Output is correct
4 Correct 7 ms 1528 KB Output is correct
5 Runtime error 3452 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 2268 KB Output is correct
2 Correct 27 ms 2780 KB Output is correct
3 Correct 36 ms 3320 KB Output is correct
4 Correct 45 ms 3832 KB Output is correct
5 Runtime error 3686 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 432 KB Output is correct
2 Correct 3 ms 504 KB Output is correct
3 Correct 1 ms 504 KB Output is correct
4 Correct 5 ms 632 KB Output is correct
5 Correct 3 ms 632 KB Output is correct
6 Correct 5 ms 632 KB Output is correct
7 Correct 2 ms 504 KB Output is correct
8 Execution timed out 5032 ms 305404 KB Time limit exceeded
9 Halted 0 ms 0 KB -