Codeforces 739 B (트 리 경로 증가 및 차이 점)

나의 사 고 를 비교적 시험 하 는 좋 은 문제.
우선 DFS 를 만들어 t [i] [j] 와 d [i] [j] 를 미리 처리 합 니 다.t [i] [j] 는 i 번 째 노드 에서 2 번 째 ^ j 와 가 까 운 조상 까지, d [i] [j] 는 i 부터 t [i] [j] 까지 의 경로 가중치 총 화 를 나타 낸다.
첫 번 째 DFS 와 동시에 노드 x 에 대해 포 지 셔 닝 (결 과 는 dist (x, y) < = a (y)) 의 x 에서 가장 먼 x 의 한 조상 을 정 한 다음 에 O (1) 의 차 이 를 한다.
1 차 DFS 를 완성 한 뒤 2 차 DFS 통계 답안 (차분 집계 후 결과) 을 작성 한다.시간 복잡 도 O (NgN)
코드 드 립 니 다.
#include 

using namespace std;

#define REP(i,n)                for(int i(0); i <  (n); ++i)
#define rep(i,a,b)              for(int i(a); i <= (b); ++i)
#define dec(i,a,b)              for(int i(a); i >= (b); --i)
#define for_edge(i,x)           for(int i = H[x]; i; i = X[i])

#define LL      long long
#define ULL     unsigned long long
#define MP      make_pair
#define PB      push_back
#define FI      first
#define SE      second
#define INF     1 << 30
#define sz(x)	(int)x.size()

const int N     =    200000      +       10;
const int M     =    10000       +       10;
const int Q     =    1000        +       10;
const int A     =    30          +       1;


vector  v[N], c[N];
LL a[N], deep[N];
LL x, y;
int n, cnt;
LL t[N][A], d[N][A];
LL g[N], value[N];
LL s[N];
LL ans[N];

void dfs(int x, int fa){
	if (g[x]){
		t[x][0] = g[x];
		d[x][0] = value[x];
		for (int i = 0; t[t[x][i]][i]; ++i){
			t[x][i + 1] = t[t[x][i]][i];
			d[x][i + 1] = d[t[x][i]][i] + d[x][i];
		}
		int now = x, noww = 0;
		bool flag = false;
		dec(i, 20, 0){
			if (t[now][i] && d[now][i] + noww <= a[x]){
				noww += d[now][i];
				now = t[now][i];
				flag = true;
			}
		}
		if (flag){
			--s[g[now]]; ++s[g[x]];
		}
	}

	REP(i, sz(v[x])){
		int u = v[x][i];
		deep[u] = deep[x] + 1;
		dfs(u, x);
	}
}

void dfs2(int x){
	ans[x] += s[x];
	REP(i, sz(v[x])){
		dfs2(v[x][i]);
		ans[x] += ans[v[x][i]];
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("test.txt", "r", stdin);
	freopen("test.out", "w", stdout);
#endif

	scanf("%d", &n);
	rep(i, 1, n) scanf("%lld", a + i);
	rep(i, 2, n){
		scanf("%lld%lld", &x, &y); g[i] = x; value[i] = y;
		v[x].PB(i), c[x].PB(y);
	}

	memset(s, 0, sizeof s);
	cnt = 0;
	deep[1] = 0;
	dfs(1, 0);
	memset(ans, 0, sizeof ans);
	dfs2(1);
	rep(i, 1, n - 1) printf("%lld ", ans[i]);
	printf("%lld
", ans[n]); return 0; }

좋은 웹페이지 즐겨찾기