Official

E - Family and Insurance Editorial by m_99


\(\mathrm{dp}_i\) を「人 \(i\) は最大で何代先まで補償対象者か」とします。ただし、人 \(i\) 自身が最後ならば \(\mathrm{dp}_i = 0\)、人 \(i\) が保障対象者でないならば \(\mathrm{dp}_i =-1\) です。
ここで、\(m_i\)\(x_j=i\) を満たす \(j\) に対する \(y_j\) の最大値(存在しなければ \(-1\) とすると、\(\mathrm{dp}_i = \max(m_i, \mathrm{dp}_{p_i}-1 )\) です( \(i=1\) の時は \(p_i\) が定まらないので前者のみ)。これを \(i\) の昇順に求め、\(\mathrm{dp}_i \geq 0\) を満たす \(i\) の個数を出力することで正答できます。

実装例(C++)

#include <bits/stdc++.h>
using namespace std;
	
int main() {
    
	int N,M;
	cin>>N>>M;
	
	vector<int> p(N);
	
	for(int i=1;i<N;i++){
		cin>>p[i];
		p[i]--;
	}
	
	vector<int> dp(N,-1);
	
	for(int i=0;i<M;i++){
		int x,y;
		cin>>x>>y;
		x--;
		dp[x] = max(dp[x],y);
	}
	
	for(int i=1;i<N;i++){
		dp[i] = max(dp[i],dp[p[i]]-1);
	}
	
	int ans = 0;
	for(int i=0;i<N;i++){
		if(dp[i]>=0)ans++;
	}
	
	cout<<ans<<endl;
	
	return 0;
}

posted:
last update: