제출 #1237089

#제출 시각아이디문제언어결과실행 시간메모리
1237089EliudGarciaPlahte (COCI17_plahte)C++17
0 / 160
242 ms51404 KiB
#include <bits/stdc++.h> using namespace std; #define ln '\n' #define all(x) x.begin(), x.end() #define forn(i, n) for(int i = 0; i < n; i++) #define forab(i, a, b) for (int i = a; i < b; i++) #define pb push_back #define sz(x) int(x.size()) #define rforn(i, n) for (int i = n-1; i >= 0; --i) #define form(i, n, m, x) for (int i = n; i < m; i += x) #define rform(i, n, m, x) for (int i = n; i >= m; i -= x) #ifdef LOCAL #include "debug.cpp" #else #define dbg(...) #endif typedef long long ll; typedef vector<int> vi; typedef vector<bool> vb; typedef vector<ll> vll; template<typename T> void print(T *a, int l, int r){ cout << "===> ["; for(int i = l; i < r; i++){ if(i == r - 1) cout << (a[i]) << "]\n"; else cout << a[i] << ", "; } } template<typename T> struct STree { int n; vector<T> st, lazy; T neutro = T(0); STree(int m) { n = m; st.resize(n * 4); lazy.resize(n * 4); } STree(vector<T> &a) { n = sz(a); st.resize(n * 4); lazy.resize(n * 4); build(1, 0, n - 1, a); } T oper(T a, T b) { return max(a, b); } void build(int v, int tl, int tr, vector<T> &a) { if(tl == tr) { st[v] = a[tl]; return; } int tm = (tl + tr) / 2; build(v * 2, tl, tm, a); build(v * 2 + 1, tm + 1, tr, a); st[v] = oper(st[v * 2], st[v * 2 + 1]); } void push(int v, int tl, int tr) { if (!lazy[v]) return; st[v] = lazy[v]; if (tl != tr) { lazy[v * 2] = lazy[v]; lazy[v * 2 + 1] = lazy[v]; } lazy[v] = 0; } void upd(int v, int tl, int tr, int l, int r, T val) { push(v, tl, tr); if(tr < l || tl > r) return; if (tl >= l && tr <= r) { lazy[v] = val; push(v, tl, tr); return; } int tm = (tl + tr) / 2; upd(v * 2, tl, tm, l, r, val); upd(v * 2 + 1, tm + 1, tr, l, r, val); st[v] = oper(st[v * 2], st[v * 2 + 1]); } T query(int v, int tl, int tr, int l, int r) { push(v, tl, tr); if(tl > r || tr < l) return neutro; if (l <= tl && tr <= r) return st[v]; int tm = (tl + tr) / 2; return oper(query(v * 2, tl, tm, l, r), query(v * 2 + 1, tm + 1, tr, l, r)); } void upd(int l, int r, T val) { upd(1, 0, n - 1, l, r, val); } T query(int l, int r) { return query(1, 0, n - 1, l, r); } }; struct event { int x, y, id, is_rec, is_end; bool operator <(event &o) const { if(x == o.x){ if(is_rec && !is_end){ return is_rec > o.is_end; }else{ return is_rec < o.is_end; } } return x < o.x; } }; int n, m; const int MAXN = 80005; int color[MAXN]; int parent[MAXN]; set<int> cc[MAXN]; map<int, int> sack[MAXN]; vi compresion; vector<event> barrido; vi g[MAXN]; int sub_sz[MAXN]; int ans[MAXN]; bool vis[MAXN]; void dfs1(int u, int p){ if(vis[u]) return; vis[u] = 1; sub_sz[u] = 1; for(int v: g[u]){ if(v == p) continue; dfs1(v, u); sub_sz[u] += sub_sz[v]; } } void dfs2(int u, int p){ if(vis[u]) return; int big = -1, mx = -1; vis[u] = 1; for(int v: g[u]){ if(v == p) continue; if(sub_sz[v] > mx){ mx = sub_sz[v]; big = v; } } for(int v: g[u]){ if(v == p || v == big) continue; dfs2(v, u); } if(big != -1){ dfs2(big, u); swap(sack[u], sack[big]); //ahora u tiene el set mas grande } //small to large for(int v: g[u]){ if(v == p || v == big) continue; for(auto [c, occ] : sack[v]){ sack[u][c] += occ; } } for(int i: cc[u]){ sack[u][i]++;//incluir u } //ans queries ans[u] = sz(sack[u]); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif cin >> n >> m; vector<array<int, 2>> rect(n + 1); forn(i, n){ int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; barrido.pb({x1, y1, i + 1, 1, 0}); //inicio barrido.pb({x2, y2, i + 1, 1, 1}); //fin int alto = abs(y2 - y1); int ancho = abs(x2 - x1); rect[i + 1] = {alto, ancho}; } forn(i, m){ int x, y, c; cin >> x >> y >> c; barrido.pb({x, y, i + 1, 0, 0}); color[i + 1] = c; } // sweep line sort(all(barrido)); forn(i, sz(barrido)){ int x = barrido[i].x; int y = barrido[i].y; compresion.pb(x); compresion.pb(y); } //compresion de coordenadas sort(all(compresion)); compresion.erase(unique(all(compresion)), compresion.end()); int tam = sz(compresion) + 5; vi aux(tam, n + 2); STree<int> st(aux); for(auto [x, y, id, is_rec, is_end] : barrido){ int ny = lower_bound(all(compresion), y) - compresion.begin(); //rectangulo if(is_rec){ //dbg(x, y, "r"); if(!is_end){ int l = ny; int r = ny + rect[id][0]; //rango = [y1 + altura, y1] //settear el rango a i parent[id] = st.query(l, r); //----------- st.upd(l, r, id); }else{ int r = ny; int l = ny - rect[id][0]; int p = parent[id]; st.upd(l, r, p); } }else if(!is_rec){ //punto //dbg(x, y, "P"); int contenido = st.query(ny, ny); //dbg(contenido); cc[contenido].insert(color[id]); } } int root = 0; forab(i, 1, n + 1){ if(parent[i] == n + 2){ root = i; continue; } g[parent[i]].pb(i); g[i].pb(parent[i]); } forab(i, 1, n + 1){ if(!vis[i]) dfs1(i, 0); } fill(vis + 1, vis + n + 1, 0); forab(i, 1, n + 1){ if(!vis[i]) dfs2(i, 0); } /*dbg(cc[1]); dbg(cc[2]); dbg(cc[3]); */ forab(i, 1, n + 1){ cout << ans[i] << ln; } return 0; }
#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...