#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
synchronization.cpp: In instantiation of 'void centroidDecomp<SZ>::doStuff(int) [with int SZ = 100001]':
synchronization.cpp:182:16: required from 'void centroidDecomp<SZ>::solve(int) [with int SZ = 100001]'
synchronization.cpp:204:16: required from here
synchronization.cpp:129:45: warning: unused variable 'b' [-Wunused-variable]
for (auto a: tc[i.f]) for (auto b: a.s) {
^
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |
# |
Verdict |
Execution time |
Memory |
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 |