Submission #1047915

#TimeUsernameProblemLanguageResultExecution timeMemory
1047915flappybirdSweeping (JOI20_sweeping)C++17
22 / 100
3890 ms489352 KiB
//#define LOCAL #include <bits/stdc++.h> #include <cassert> #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx,avx2,fma") using namespace std; typedef long long ll; typedef pair<ll, ll> pll; typedef pair<int, int> pii; #define MAX 2010101 #define MAXQ 101010 #define INF 1'000'000'100 #define bb ' ' #define ln '\n' #define Ln '\n' #define MOD 1000000007 #define TC 1 #ifdef LOCAL #define DEBUG(a) cout<<a #define TEST true #else #define DEBUG(...) 1234 #define TEST false #endif int N, M, Q; //points int X[MAX]; int Y[MAX]; int S[MAX]; vector<int> es[MAX]; //queries int T[MAX]; int L[MAX]; pii ans[MAX]; vector<int> qv[MAX]; struct node { int val; int key; int p, n; int lnk; node(int k = 0, int v = 0, int p = 0, int n = 0) :p(p), n(n) { val = v; key = k; lnk = 0; } }; vector<node> MEM; void disc(int n) { if (MEM[n].p) MEM[MEM[n].p].n = MEM[n].n; if (MEM[n].n) MEM[MEM[n].n].p = MEM[n].p; MEM[n].p = MEM[n].n = 0; } int make_node(int k, int v, int p = 0, int n = 0) { int s = MEM.size(); MEM.push_back(node(k, v, p, n)); return s; } struct Dat { int sv[2] = { 0, 0 }; //linked list int ev[2] = { 0, 0 }; int cap[2] = { 0, 0 }; //cap from down int N; void init(vector<int> K, vector<vector<int>> X) { vector<pii> ord; N = K.size(); int i; for (i = 0; i < N; i++) ord.emplace_back(i, 0); sort(ord.begin(), ord.end(), [&](pii i, pii j) {return X[0][i.first] < X[0][j.first]; }); int pv = 0; for (auto& v : ord) { int nn = make_node(K[v.first], X[0][v.first], pv); if (!sv[0]) sv[0] = nn; ev[0] = nn; v.second = nn; if (pv) MEM[pv].n = nn; pv = nn; } sort(ord.begin(), ord.end(), [&](pii i, pii j) {return X[1][i.first] < X[1][j.first]; }); pv = 0; for (auto& v : ord) { int nn = make_node(K[v.first], X[1][v.first], pv); if (!sv[1]) sv[1] = nn; ev[1] = nn; if (pv) MEM[pv].n = nn; MEM[nn].lnk = v.second; MEM[v.second].lnk = nn; pv = nn; } } int& begin(int c) { return sv[c]; } int& rbegin(int c) { return ev[c]; } node& front(int c) { return MEM[sv[c]]; } node& back(int c) { return MEM[ev[c]]; } }; vector<Dat> lists; int flag; // flag for divide function int divide(Dat& D, int c, int L) { int op = c ^ 1; int n = D.N; if (max(D.cap[c], D.front(c).val) >= L) { flag = 0; return -1; } if (max(D.cap[c], D.back(c).val) < L) { flag = 1; return -1; } int i; int chk = 0; int rem = 0; // remove int s, e; s = D.begin(c); e = D.rbegin(c); for (i = 0; i < n; i++) { if (max(D.cap[c], MEM[s].val) >= L) { chk = 0; rem = i; break; } if (max(D.cap[c], MEM[e].val) < L) { chk = 1; rem = i; break; } s = MEM[s].n; e = MEM[e].p; } Dat nd; nd.cap[0] = D.cap[0]; nd.cap[1] = D.cap[1]; s = D.begin(c); e = D.rbegin(c); nd.N = rem; if (chk) { //remove from back e = D.rbegin(c); vector<int> rems; for (i = 0; i < rem; i++) { int opn = MEM[e].lnk; assert(opn); assert(e); if (opn == D.begin(op)) D.begin(op) = MEM[opn].n; if (opn == D.rbegin(op)) D.rbegin(op) = MEM[opn].p; disc(opn); rems.push_back(opn); e = MEM[e].p; } int ns = MEM[e].n; // [list 1(original)] ... e / ns ... [list 2(new)] MEM[e].n = 0; MEM[ns].p = 0; // D.sv[op], D.ev[op] is correct sort(rems.begin(), rems.end()); for (i = 1; i < rem; i++) { MEM[rems[i - 1]].n = rems[i]; MEM[rems[i]].p = rems[i - 1]; assert(MEM[rems[i - 1]].val <= MEM[rems[i]].val); } nd.sv[c] = ns; nd.sv[op] = rems[0]; nd.ev[c] = D.ev[c]; nd.ev[op] = rems.back(); D.ev[c] = e; flag = 0; } else { // remove from front s = D.begin(c); vector<int> rems; for (i = 0; i < rem; i++) { int opn = MEM[s].lnk; assert(opn); assert(e); if (opn == D.begin(op)) D.begin(op) = MEM[opn].n; if (opn == D.rbegin(op)) D.rbegin(op) = MEM[opn].p; disc(opn); rems.push_back(opn); s = MEM[s].n; } int ne = MEM[s].p; // [list 1(new)] ... ne / s ... [list 2(original)] MEM[s].p = 0; MEM[ne].n = 0; // D.sv[op], D.ev[op] is correct sort(rems.begin(), rems.end()); for (i = 1; i < rem; i++) { MEM[rems[i - 1]].n = rems[i]; MEM[rems[i]].p = rems[i - 1]; } nd.sv[c] = D.sv[c]; nd.sv[op] = rems[0]; nd.ev[c] = ne; nd.ev[op] = rems.back(); D.sv[c] = s; flag = 1; } D.N = n - rem; lists.push_back(nd); return lists.size() - 1; } void solve(int l, int r, vector<int>& v) { lists.clear(); MEM.clear(); MEM.push_back(node()); int i; int n = v.size(); vector<int> K(n); vector<vector<int>> val(2, vector<int>(K.size())); for (i = 0; i < n; i++) { K[i] = v[i]; val[0][i] = X[v[i]]; val[1][i] = Y[v[i]]; } Dat d; d.init(K, val); lists.push_back(d); set<pii> st; // (left top point of the triangle, index in lists) st.emplace(-2, 0); for (i = l; i <= r; i++) { if (T[i] == 1 || T[i] == 4) continue; if (T[i] == 2) { int v = N - L[i]; auto it = st.lower_bound(pii(v, 0)); it--; int pv = it->first; int ind1 = it->second; st.erase(it); int ind2 = divide(lists[ind1], 1, L[i] + 1); if (!~ind2) { if (flag) lists[ind1].cap[0] = max(lists[ind1].cap[0], v); st.emplace(pv, ind1); continue; } if (flag) { //reversed st.emplace(pv, ind1); st.emplace(v, ind2); lists[ind2].cap[0] = max(lists[ind2].cap[0], v); } else { st.emplace(pv, ind2); st.emplace(v, ind1); lists[ind1].cap[0] = max(lists[ind1].cap[0], v); } } else { int v = N - L[i]; auto it = st.lower_bound(pii(L[i] + 1, 0)); it--; int pv = it->first; int ind1 = it->second; st.erase(it); int ind2 = divide(lists[ind1], 0, L[i] + 1); if (!~ind2) { if (flag) lists[ind1].cap[1] = max(lists[ind1].cap[1], v); st.emplace(pv, ind1); continue; } if (flag) { //reversed st.emplace(pv, ind2); st.emplace(L[i], ind1); lists[ind2].cap[1] = max(lists[ind2].cap[1], v); } else { st.emplace(pv, ind1); st.emplace(L[i], ind2); lists[ind1].cap[1] = max(lists[ind1].cap[1], v); } } } for (auto& d : lists) { assert(!MEM[d.sv[0]].p); assert(!MEM[d.sv[1]].p); assert(!MEM[d.ev[0]].n); assert(!MEM[d.ev[1]].n); int s = d.sv[0]; for (i = 0; i < d.N; i++) { int v = MEM[s].key; X[v] = max(X[v], d.cap[0]); Y[v] = max(Y[v], d.cap[1]); if (qv[v].size() && qv[v].back() == r) { ans[qv[v].back()] = pii(X[v], Y[v]); qv[v].pop_back(); } s = MEM[s].n; } } } vector<int> tree[MAX * 4]; vector<tuple<int, int, int>> vt; void init(int s, int e, int loc = 1) { vt.emplace_back(s, e, loc); if (s == e) return; int m = s + e >> 1; init(s, m, loc * 2); init(m + 1, e, loc * 2 + 1); } void add(int s, int e, int l, int r, int v, int loc = 1) { if (e < l || r < s) return; if (l <= s && e <= r) { tree[loc].push_back(v); return; } int m = s + e >> 1; add(s, m, l, r, v, loc * 2); add(m + 1, e, l, r, v, loc * 2 + 1); } #ifdef LOCAL #define cin fin ifstream fin("C:\\Users\\flapp\\Downloads\\sweeping-data\\in\\04-10.txt"); #endif signed main() { #ifndef LOCAL ios::sync_with_stdio(false), cin.tie(0); #endif cin >> N >> M >> Q; int i, x; for (i = 1; i <= M; i++) { cin >> X[i] >> Y[i]; S[i] = 1; } init(1, Q); for (i = 1; i <= Q; i++) { cin >> T[i]; if (T[i] == 1) { cin >> x; if (qv[x].empty()) add(1, Q, S[x], i, x); else add(1, Q, qv[x].back() + 1, i, x); qv[x].push_back(i); } if (T[i] == 2 || T[i] == 3) cin >> L[i]; if (T[i] == 4) { S[++M] = i; cin >> X[M] >> Y[M]; } } for (i = 1; i <= M; i++) reverse(qv[i].begin(), qv[i].end()); sort(vt.begin(), vt.end()); for (auto& [l, r, v] : vt) if (tree[v].size()) solve(l, r, tree[v]); for (i = 1; i <= Q; i++) if (T[i] == 1) cout << ans[i].first << bb << ans[i].second << ln; }

Compilation message (stderr)

sweeping.cpp: In function 'void init(int, int, int)':
sweeping.cpp:318:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  318 |  int m = s + e >> 1;
      |          ~~^~~
sweeping.cpp: In function 'void add(int, int, int, int, int, int)':
sweeping.cpp:329:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  329 |  int m = s + e >> 1;
      |          ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...