kou6839の日記

c++ 競プロ(特にcsacademy) linuxについて書きます。普段は自動車屋さんでナビ開発してます。転職先を探しています!!。

CSAcademy Prefix Matches

csacademy.com

<問題>
長さNの文字列S、サイズN-1の配列A,Bが与えられます。
A_iSi番目の文字から何文字がSのprefixと一致するかを表します。
B_iSi番目で終わる部分文字列のうち何文字がSのprefixと一致するかを表します。

Aが与えられたときBを答えよ。


<解説>
Bの更新方法には2種類あります。
1.
i文字目からA_i文字がSのprefixと一致するので、B[i+A_i-1]=max(B[i+A_i-1],A_i)となります。
(Aから○文字がprefixと一致するなら逆からみても一致します。)

2.
B_i = max(B_i,B_{i+1}-1)
iからj文字目がsのprefixと一致しているならiからj-1文字目も一致します)



<コード>

int main() {

	int n;
	cin >> n;
	vi a(n), b(n);
	for (int i = 1; i < n; i++) {
		cin >> a[i];
	}

	for (int i = 1; i < n; i++) {
		b[i + a[i] - 1] = max(b[i + a[i] - 1], a[i]);
	}

	for (int i = n - 2; i > 0; i--) {
		b[i] = max(b[i],b[i+1]-1);
	}

	for (int i = 1; i < n; i++) {
		if (i != n - 1) {
			cout << b[i] << " ";
		}
		else {
			P(b[i]);
		}
	}

	return 0;
}

<感想>
問題文を理解するのに時間がかかった