# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
70371 | 2018-08-22T17:25:52 Z | Benq | 동기화 (JOI13_synchronization) | C++14 | 2230 ms | 140216 KB |
#pragma GCC optimize ("O3") #pragma GCC target ("sse4") #include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> #include <ext/rope> using namespace std; using namespace __gnu_pbds; using namespace __gnu_cxx; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 100001; int N,M,Q, X[MX], Y[MX]; vi change[MX]; int numLE(vi& v, int x) { return distance(v.begin(),ub(all(v),x)); } void merge(vi& a, vi& b) { if (sz(a) < sz(b)) swap(a,b); a.insert(a.end(),all(b)); } void comb(map<int,vi>& a, map<int,vi>& b) { if (sz(a) < sz(b)) swap(a,b); for (auto& x: b) merge(a[x.f],x.s); b.clear(); } template<int SZ> struct centroidDecomp { int sub[SZ], par[SZ]; bool done[SZ]; pi cen[SZ]; vi fromCentroid[SZ]; // from (cen) to (vertex at time N) vi stor[SZ]; vector<vi> stor2[SZ]; // from (vertex at time 1) to cen vpi adj[SZ]; // ACTUAL map<int,vi> fc[MX], tc[MX]; void elimfc(map<int,vi>& m, int x) { for (int i = 0; i <= sz(change[x]); i += 2) { int l = (i > 0 ? change[x][i-1] : -MOD); int r = (i == sz(change[x]) ? MOD : change[x][i]-1); while (1) { auto it = m.ub(l); if (it != m.end() && it->f <= r) { merge(m[l],it->s); m.erase(it); } else break; } } } void elimtc(map<int,vi>& m, int x) { for (int i = 0; i <= sz(change[x]); i += 2) { int l = (i > 0 ? change[x][i-1]+1 : -MOD), r = (i == sz(change[x]) ? MOD : change[x][i]); while (1) { auto it = m.lb(l); if (it != m.end() && it->f < r) { merge(m[r],it->s); m.erase(it); } else break; } } } void gen(pi par, int no) { fc[no].clear(), tc[no].clear(); fc[no][M].pb(no); tc[no][1].pb(no); for (auto i: adj[no]) if (!done[i.f] && i.f != par.f) { cen[i.f] = cen[no]; gen({no,i.s},i.f); comb(fc[no],fc[i.f]); comb(tc[no],tc[i.f]); } elimfc(fc[no],par.s); elimtc(tc[no],par.s); } void doStuff(int x) { fromCentroid[x].pb(M); stor[x].pb(1); int co = 0; for (auto i: adj[x]) if (!done[i.f]) { cen[i.f] = {x,co}; stor2[x].pb({}); gen({x,i.s},i.f); for (auto a: fc[i.f]) for (auto b: a.s) { fromCentroid[b].pb(a.f); // cout << "AH " << x << " " << b << " " << a.f << "\n"; } for (auto a: tc[i.f]) for (auto b: a.s) { stor[x].pb(a.f); stor2[x][co].pb(a.f); } co ++; } /*cout << x << "\n"; for (int i: stor[x]) cout << i << " "; exit(0);*/ sort(all(stor[x])); F0R(i,co) sort(all(stor2[x][i])); } int query(int v) { int ret = 0; pi V; int ind; for (V = {v,-1}, ind = sz(fromCentroid[v])-1; V.f; V = cen[V.f], ind --) { int d = fromCentroid[v][ind]; // cout << "OOPS " << v << " " << V.f << " " << d << "\n"; // cout << "OOPS " << d << "\n"; ret += numLE(stor[V.f],d); if (V.s != -1) ret -= numLE(stor2[V.f][V.s],d); } return ret; } // centroid decomp void addEdge(int a, int b, int c) { adj[a].pb({b,c}), adj[b].pb({a,c}); } void dfs (int no) { sub[no] = 1; for (auto i: adj[no]) if (!done[i.f] && i.f != par[no]) { par[i.f] = no; dfs(i.f); sub[no] += sub[i.f]; } } int getCentroid(int x) { par[x] = 0; dfs(x); int sz = sub[x]; while (1) { pi mx = {0,0}; for (auto i: adj[x]) if (!done[i.f] && i.f != par[x]) mx = max(mx,{sub[i.f],i.f}); if (mx.f*2 > sz) x = mx.s; else return x; } } void solve (int x) { x = getCentroid(x); done[x] = 1; doStuff(x); for (auto i: adj[x]) if (!done[i.f]) solve(i.f); } }; centroidDecomp<MX> cen; void init() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> M >> Q; FOR(i,1,N) { cin >> X[i] >> Y[i]; cen.addEdge(X[i],Y[i],i); } FOR(i,1,M+1) { int D; cin >> D; change[D].pb(i); } } int main() { init(); cen.solve(1); F0R(i,Q) { int C; cin >> C; cout << cen.query(C) << "\n"; } } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds * if you have no idea just guess the appropriate well-known algo instead of doing nothing :/ */
Compilation message
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 30 ms | 22232 KB | Output is correct |
2 | Correct | 26 ms | 22256 KB | Output is correct |
3 | Correct | 28 ms | 22308 KB | Output is correct |
4 | Correct | 26 ms | 22440 KB | Output is correct |
5 | Correct | 24 ms | 22552 KB | Output is correct |
6 | Correct | 35 ms | 23176 KB | Output is correct |
7 | Correct | 166 ms | 28288 KB | Output is correct |
8 | Correct | 144 ms | 28444 KB | Output is correct |
9 | Correct | 180 ms | 28748 KB | Output is correct |
10 | Correct | 1920 ms | 83608 KB | Output is correct |
11 | Correct | 2041 ms | 85980 KB | Output is correct |
12 | Correct | 1805 ms | 94796 KB | Output is correct |
13 | Correct | 330 ms | 94796 KB | Output is correct |
14 | Correct | 1753 ms | 94796 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 1110 ms | 94796 KB | Output is correct |
2 | Correct | 1187 ms | 94796 KB | Output is correct |
3 | Correct | 1886 ms | 103608 KB | Output is correct |
4 | Correct | 2094 ms | 105504 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 28 ms | 105504 KB | Output is correct |
2 | Correct | 26 ms | 105504 KB | Output is correct |
3 | Correct | 27 ms | 105504 KB | Output is correct |
4 | Correct | 26 ms | 105504 KB | Output is correct |
5 | Correct | 23 ms | 105504 KB | Output is correct |
6 | Correct | 36 ms | 105504 KB | Output is correct |
7 | Correct | 156 ms | 105504 KB | Output is correct |
8 | Correct | 1941 ms | 109304 KB | Output is correct |
9 | Correct | 1890 ms | 112204 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 1987 ms | 115292 KB | Output is correct |
2 | Correct | 2074 ms | 117032 KB | Output is correct |
3 | Correct | 2098 ms | 119568 KB | Output is correct |
4 | Correct | 2094 ms | 121848 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 25 ms | 121848 KB | Output is correct |
2 | Correct | 25 ms | 121848 KB | Output is correct |
3 | Correct | 27 ms | 121848 KB | Output is correct |
4 | Correct | 26 ms | 121848 KB | Output is correct |
5 | Correct | 35 ms | 121848 KB | Output is correct |
6 | Correct | 151 ms | 121848 KB | Output is correct |
7 | Correct | 2125 ms | 121848 KB | Output is correct |
8 | Correct | 1850 ms | 127944 KB | Output is correct |
9 | Correct | 302 ms | 127944 KB | Output is correct |
10 | Correct | 2230 ms | 127944 KB | Output is correct |
11 | Correct | 1231 ms | 127944 KB | Output is correct |
12 | Correct | 1148 ms | 129012 KB | Output is correct |
13 | Correct | 2041 ms | 140216 KB | Output is correct |