Submission #1204054

#TimeUsernameProblemLanguageResultExecution timeMemory
1204054notmeWerewolf (IOI18_werewolf)C++20
0 / 100
157 ms61940 KiB
#include <bits/stdc++.h> #define pb push_back #include "werewolf.h" using namespace std; const int maxn = 2e5 + 10; int n, m, q; vector < int > g[maxn]; struct query { int l, r, s, e; query(){}; query(int _l, int _r, int _s, int _e) { l = _l; r = _r; s = _s; e = _e; } }; int t[maxn * 4]; int ql, qr; int doquery(int i, int l, int r) { if(qr < l || ql > r)return 0; if(ql <= l && r <= qr)return t[i]; int mid = (l + r)/2; return doquery(2*i, l, mid) + doquery(2*i+1, mid+1, r); } int make_query(int queryl, int queryr) { ql = queryl; qr = queryr; return doquery(1, 1, n); } int updpos, updval; void update(int i, int l, int r) { if(l == r) { t[i] = updval; return; } int mid = (l + r)/2; if(updpos <= mid)update(2*i, l, mid); else update(2*i+1, mid+1, r); t[i] = t[2*i] + t[2*i+1]; } void make_update(int pos, int val) { updpos = pos; updval = val; update(1, 1, n); } query ask[maxn]; vector < int > emax, emin; int pos[maxn]; struct dsu_tree /// mintree -> pref, ends in n-1 { /// maxtree -> suff, ends in 0 int tmr; vector < int > p; vector < int > tin, tout; vector < vector < int > > adj; vector < vector < int > > jump; vector < int > used; dsu_tree(int n) { tmr = 0; used.resize(n, 0); p.resize(n); tin.resize(n); tout.resize(n); adj.resize(n); jump.resize(n); for (int i = 0; i < n; ++ i) { p[i] = i; } } /// dsu stuff int find_leader(int i) { if(p[i] == i)return i; return (p[i] == find_leader(p[i])); } void add_edge(int v, int type) { int leadv = find_leader(v); for (auto u: g[v]) { if(u > v && type == 0)continue; if(u < v && type == 1)continue; if(type == 0) { // cout << "add " << u << " " << v << endl; } int leadu = find_leader(u); if(leadv == leadu)continue; if(type == 0) { //cout << v << " " << leadu << endl; } p[leadu] = leadv; adj[v].pb(leadu); adj[leadu].pb(v); } } /// euler stuff void euler(int beg, int from, bool type) { used[beg] = 1; //cout << beg << endl; jump[beg].resize(20); jump[beg][0] = from; for (int j = 1; j < 20; ++ j) { if(jump[beg][j-1] == -1) { jump[beg][j] = -1; continue; } jump[beg][j-1] = jump[jump[beg][j-1]][j-1]; } tmr ++; tin[beg] = tmr; if(type) pos[beg] = tmr; if(type == 0) emin.pb(beg); else emax.pb(beg); for (auto nb: adj[beg]) { if(used[nb])continue; euler(nb, beg, type); } tout[beg] = tmr; } }; struct segm { int lmax, rmax, lmin, rmin; segm(){}; segm(int _lmax, int _rmax, int _lmin, int _rmin) { lmax = _lmax; rmax = _rmax; lmin = _lmin; rmin = _rmin; } }; std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y, std::vector<int> S, std::vector<int> E, std::vector<int> L, std::vector<int> R) { n = N; m = L.size(); q = S.size(); for (int i = 0; i < X.size(); ++ i) { int from = X[i], to = Y[i]; g[from].pb(to); g[to].pb(from); } for (int i = 0; i < m; ++ i) { ask[i] = query(L[i], R[i], S[i], E[i]); } dsu_tree mintree(n), maxtree(n); for (int i = 0; i < n; ++ i) mintree.add_edge(i, 0); for (int i = n-1; i >= 0; -- i) maxtree.add_edge(i, 1); mintree.euler(n-1, -1, 0); maxtree.euler(0, -1, 1); std::vector < int > ans; vector < segm > sg; ans.resize(q, 0); vector < vector < int > > st, fi; st.resize(n+1); fi.resize(n+1); for (int i = 0; i < m; ++ i) { int from = ask[i].s; int to = ask[i].e; for (int bit = 19; bit >= 0; -- bit) { if(maxtree.jump[from][bit] != -1 && maxtree.jump[from][bit] >= ask[i].l) from = maxtree.jump[from][bit]; } for (int bit = 19; bit >= 0; -- bit) { if(mintree.jump[from][bit] != -1 && mintree.jump[from][bit] <= ask[i].r) to = mintree.jump[from][bit]; } // cout << "real " << from << " " << to << endl; sg.pb(segm(maxtree.tin[from], maxtree.tout[from], mintree.tin[to], maxtree.tout[to])); /// from in maxtree, to in mintree } for (int i = 0; i < sg.size(); ++ i) { int lt = sg[i].lmin, rt = sg[i].rmin; fi[lt - 1].pb(i); st[rt].pb(i); } for (int i = 1; i <= n; ++ i) { make_update(pos[i], 1); for (auto &x: fi[i]) { long long num = make_query(sg[x].lmax, sg[x].rmax); ans[x] -= num; //make_query(segm[x].lmax, segm[x].rmax); } for (auto &x: st[i])ans[x] += make_query(sg[x].lmax, sg[x].rmax); } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...