Submission #130173

#TimeUsernameProblemLanguageResultExecution timeMemory
130173choikiwonWorst Reporter 2 (JOI16_worst_reporter2)C++17
100 / 100
632 ms71388 KiB
#include<bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int MN = 200010; int N; vector<int> V[MN], X[MN], L[MN]; priority_queue<int> freeV; multiset<int> freeX; struct BIT { int Z; vector<pii> tree; vector<int> lazy; void init(int Z_) { Z = Z_; tree = vector<pii>(4 * Z); lazy = vector<int>(4 * Z, 0); build(0, Z - 1, 1); } void build(int l, int r, int n) { if(l == r) { tree[n] = {0, -l}; return; } int m = (l + r)>>1; build(l, m, 2*n); build(m + 1, r, 2*n + 1); tree[n] = min(tree[2*n], tree[2*n + 1]); } void prop(int l, int r, int n) { if(l != r) { tree[2*n].first += lazy[n]; lazy[2*n] += lazy[n]; tree[2*n + 1].first += lazy[n]; lazy[2*n + 1] += lazy[n]; lazy[n] = 0; } } void upd(int a, int b, int d, int l, int r, int n) { if(b < l || r < a) return; if(a <= l && r <= b) { tree[n].first += d; lazy[n] += d; return; } prop(l, r, n); int m = (l + r)>>1; upd(a, b, d, l, m, 2*n); upd(a, b, d, m + 1, r, 2*n + 1); tree[n] = min(tree[2*n], tree[2*n + 1]); } pii quer(int a, int b, int l, int r, int n) { if(b < l || r < a) return pii(1e9, 1e9); if(a <= l && r <= b) return tree[n]; prop(l, r, n); int m = (l + r)>>1; pii L = quer(a, b, l, m, 2*n); pii R = quer(a, b, m + 1, r, 2*n + 1); return min(L, R); } void upd(int a, int b, int d) { upd(a, b, d, 0, Z - 1, 1); } pii quer(int a, int b) { return quer(a, b, 0, Z - 1, 1); } }; struct RMQ { int Z; vector<int> tree; void init(int Z_) { Z = Z_; tree = vector<int>(4 * Z); build(0, Z - 1, 1); } void build(int l, int r, int n) { if(l == r) { tree[n] = l; return; } int m = (l + r)>>1; build(l, m, 2*n); build(m + 1, r, 2*n + 1); tree[n] = max(tree[2*n], tree[2*n + 1]); } void upd(int x, int v, int l, int r, int n) { if(x < l || r < x) return; if(l == r) { tree[n] = v; return; } int m = (l + r)>>1; upd(x, v, l, m, 2*n); upd(x, v, m + 1, r, 2*n + 1); tree[n] = max(tree[2*n], tree[2*n + 1]); } void upd(int x, int v) { upd(x, v, 0, Z - 1, 1); } }; BIT bit[MN]; RMQ rmq[MN]; struct Info { int v, i, j, l, x, y; bool operator <(const Info &o) const { if(v != o.v) return v < o.v; if(i != o.i) return i < o.i; return j < o.j; } }; priority_queue<Info> cand, pq, P; int la[MN]; void relax() { while(!cand.empty()) { Info t = cand.top(); int x = t.j; if(t.l != la[x] || t.y != bit[x].quer(la[x], la[x]).first) { cand.pop(); continue; } break; } } int main() { std::ios::sync_with_stdio(false); cin >> N; //N = 50; for(int i = 0; i < N; i++) { int a, b; cin >> a >> b; //int a = rand() % 20 + 1; //int b = (i + 1) * (i + 1); V[--a].push_back(b); } for(int i = 0; i < N; i++) { int c, d; cin >> c >> d; //int c = rand() % 20 + 1; //int d = rand() % 10 == 0? (i + 1) * (i + 2) : (i + 1) * (i + 1); X[--c].push_back(d); } int ans = 0; for(int i = 0; i < N; i++) { sort(V[i].begin(), V[i].end()); sort(X[i].begin(), X[i].end()); vector<int> chk(V[i].size(), 0); vector<int> tmp; int pos = (int)X[i].size() - 1; for(int j = (int)V[i].size() - 1; j >= 0; j--) { if(pos >= 0 && V[i][j] <= X[i][pos]) { pos--; continue; } freeV.push(V[i][j]); chk[j] = 1; } for(int j = 0; j < V[i].size(); j++) if(!chk[j]) tmp.push_back(V[i][j]); V[i] = tmp; if(V[i].size() == 0) { for(int j = 0; j < X[i].size(); j++) { freeX.insert(X[i][j]); } la[i] = -1; continue; } bit[i].init(V[i].size()); rmq[i].init(V[i].size()); chk = vector<int>(X[i].size(), 0); pos = 0; for(int j = 0; j < V[i].size(); j++) { while(pos < X[i].size() && X[i][pos] < V[i][j]) pos++; chk[pos] = 1; pos++; P.push({V[i][j], i, j}); } tmp.clear(); for(int j = 0; j < X[i].size(); j++) { if(chk[j]) tmp.push_back(X[i][j]); else freeX.insert(X[i][j]); } X[i] = tmp; L[i].resize(V[i].size()); pos = (int)X[i].size() - 1; for(int j = (int)V[i].size() - 1; j >= 0; j--) { while(pos >= 0 && X[i][pos] >= V[i][j]) pos--; bit[i].upd(j, j, j - pos - 1); L[i][j] = pos + 1; } pii t = bit[i].tree[1]; la[i] = (int)V[i].size() - 1; pq.push({ X[i].back(), V[i][-t.second], i, la[i], -t.second, bit[i].quer(la[i], la[i]).first }); } ans += freeV.size(); while(!freeV.empty()) { int v = freeV.top(); freeV.pop(); //cout << v << endl; while(!P.empty() && P.top().v >= v) { Info t = P.top(); P.pop(); int x = t.i; if(t.j != la[x]) { continue; } bit[x].upd(la[x], la[x], 1e9); rmq[x].upd(la[x], -1); la[x] = rmq[x].tree[1]; if(la[x] >= 0) { pii t = bit[x].tree[1]; pii d = bit[x].quer(la[x], la[x]); pq.push({ X[x][ L[x][ la[x] ] + d.first ], V[x][-t.second], x, la[x], -t.second, d.first }); } } while(!pq.empty() && pq.top().v >= v) { Info t = pq.top(); pq.pop(); cand.push({ -t.i, t.v, t.j, t.l, t.x, t.y }); } auto it = freeX.lower_bound(v); if(it != freeX.end()) { freeX.erase(it); continue; } ans++; relax(); Info t = cand.top(); cand.pop(); int x = t.j; int s = t.x; int e = la[x]; bit[x].upd(s, e, -1); bit[x].upd(s, s, 1e9); rmq[x].upd(s, -1); if(s != e) { pii d = bit[x].quer(e, e); pq.push({ X[x][ L[x][e] + d.first ], V[x][ -bit[x].tree[1].second ], x, la[x], -bit[x].tree[1].second, d.first }); //cout << X[x][ L[x][e] + d.first ] << ' ' << V[x][ -bit[x].tree[1].second ] << endl; } freeV.push(V[x][s]); //cout << "push : " << x << ' ' << s << ' ' << e << ' ' << V[x][s] << endl; } cout << ans; }

Compilation message (stderr)

worst_reporter2.cpp: In function 'int main()':
worst_reporter2.cpp:165:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j = 0; j < V[i].size(); j++) if(!chk[j]) tmp.push_back(V[i][j]);
                        ~~^~~~~~~~~~~~~
worst_reporter2.cpp:169:30: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             for(int j = 0; j < X[i].size(); j++) {
                            ~~^~~~~~~~~~~~~
worst_reporter2.cpp:182:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j = 0; j < V[i].size(); j++) {
                        ~~^~~~~~~~~~~~~
worst_reporter2.cpp:183:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while(pos < X[i].size() && X[i][pos] < V[i][j]) pos++;
                   ~~~~^~~~~~~~~~~~~
worst_reporter2.cpp:191:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j = 0; j < X[i].size(); j++) {
                        ~~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...