#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define RE(a,b) REP(a,0,b)
#define RE1(a,b) REP(a,1,b+1)
#define FOR(a,b) for(auto& a : b)
#define pb push_back
#define all(a) a.begin(),a.end()
#define fi first
#define se second
const int INF = 1e9;
const int MX = 5e5;
const int N = 1<<20;
const int MOD = 1e9+7;
int n, m, q;
int a[MX], b[MX], c[MX], d[MX];
// tree stuff
vi adj[MX], chl[MX];
int par[MX], siz[MX], dep[MX];
void dfs(int u, int p) {
par[u] = p;
siz[u] = 1;
dep[u] = dep[p] + 1;
FOR(v,adj[u]) {
if(v == p) continue;
siz[u] += siz[v];
dfs(v,u);
chl[u].pb(v);
}
}
// seg
struct Seg{
int seg[N*2];
void setSeg(int i, int j, int v, int lazy=0, int p=1, int l=0, int r=N-1) {
if(lazy) seg[p] = lazy;
if(j < l || i > r) return;
if(i <= l && j >= r) {
seg[p] = v;
return;
}
int m=(l+r)/2;
setSeg(i,j,v,seg[p],p*2,l,m);
setSeg(i,j,v,seg[p],p*2+1,m+1,r);
seg[p] = 0;
}
int getSeg(int i, int lazy=0, int p=1, int l=0, int r=N-1) {
if(lazy) seg[p] = lazy;
if(i < l || i > r) return 0;
if(l == r) return seg[p];
int m=(l+r)/2;
int a=getSeg(i,seg[p],p*2,l,m);
int b=getSeg(i,seg[p],p*2+1,m+1,r);
return a+b;
}
} upseg, downseg;
// hld
int hd[MX], segi[MX], curseg=0;
void hld(int u, int head) {
hd[u] = head;
segi[u] = curseg++;
if(chl[u].empty()) return;
int bst=chl[u][0];
FOR(v,chl[u]) if(siz[v] > siz[bst]) bst = v;
hld(bst,head);
FOR(v,chl[u]) if(bst != v) hld(v,v);
}
int getRoot(int u) {
while(true) {
int nu = upseg.getSeg(segi[u]);
if(nu == u) break;
u = nu;
}
return u;
}
// problem specific
int edge[MX], vert[MX], exist[MX];
int getVal(int u) {
return vert[getRoot(u)];
}
int main() {
// input
cin>>n>>m>>q;
RE1(i,n-1) cin>>a[i]>>b[i];
RE1(i,m) cin>>d[i];
RE1(i,q) cin>>c[i];
RE1(i,n-1) adj[a[i]].pb(b[i]);
dfs(1,1);
hld(1,1);
RE1(i,n-1) if(a[i] != par[b[i]]) swap(a[i], b[i]);
RE1(i,n) downseg.setSeg(segi[i],segi[i],i);
RE1(i,n) upseg .setSeg(segi[i],segi[i],i);
RE1(i,n) vert[i] = 1;
RE1(i,m) {
if(!exist[d[i]]) {
int nval = getVal(a[d[i]]) + getVal(b[d[i]]) - edge[d[i]];
int down = downseg.getSeg(segi[b[d[i]]]);
if(hd[a[d[i]]] != hd[b[d[i]]]) {
// d[i] is not a heavy edge
upseg .setSeg(segi[b[d[i]]], segi[down], a[d[i]]);
downseg.setSeg(segi[b[d[i]]], segi[down], down);
} else {
// d[i] is a heavy edge
int up = upseg.getSeg(segi[a[d[i]]]);
int rt = dep[up] > dep[hd[b[d[i]]]] ? up : hd[b[d[i]]];
upseg.setSeg(segi[rt], segi[down], up);
downseg.setSeg(segi[rt], segi[down], down);
}
vert[getRoot(a[d[i]])] = nval;
}
else {
edge[d[i]] = getVal(a[d[i]]);
int down = downseg.getSeg(segi[b[d[i]]]);
upseg.setSeg(segi[b[d[i]]], segi[down], b[d[i]]);
vert[b[d[i]]] = edge[d[i]];
int up = upseg.getSeg(segi[a[d[i]]]);
int rt = dep[up] > dep[hd[b[d[i]]]] ? up : hd[b[d[i]]];
downseg.setSeg(segi[rt], segi[a[d[i]]], a[d[i]]);
}
exist[d[i]] = !exist[d[i]];
}
RE1(i,q) {
cout << getVal(c[i]) << endl;
}
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
15 ms |
23908 KB |
Output is correct |
2 |
Incorrect |
15 ms |
23972 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
438 ms |
37440 KB |
Output is correct |
2 |
Correct |
432 ms |
37540 KB |
Output is correct |
3 |
Correct |
383 ms |
43500 KB |
Output is correct |
4 |
Correct |
332 ms |
43584 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
15 ms |
23884 KB |
Output is correct |
2 |
Correct |
14 ms |
23884 KB |
Output is correct |
3 |
Correct |
16 ms |
24012 KB |
Output is correct |
4 |
Correct |
16 ms |
23884 KB |
Output is correct |
5 |
Correct |
18 ms |
23884 KB |
Output is correct |
6 |
Correct |
23 ms |
24140 KB |
Output is correct |
7 |
Correct |
84 ms |
26024 KB |
Output is correct |
8 |
Correct |
922 ms |
45028 KB |
Output is correct |
9 |
Correct |
823 ms |
44880 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
875 ms |
44860 KB |
Output is correct |
2 |
Correct |
566 ms |
44544 KB |
Output is correct |
3 |
Correct |
579 ms |
44544 KB |
Output is correct |
4 |
Correct |
549 ms |
44484 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
17 ms |
23884 KB |
Output is correct |
2 |
Correct |
15 ms |
23944 KB |
Output is correct |
3 |
Correct |
15 ms |
23960 KB |
Output is correct |
4 |
Incorrect |
16 ms |
23884 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |