LG11794

首先考虑如何求出原串中 JOI 的出现次数。不难想到以 O 为中心,将左边 J 与右边 I 的数量相乘再累加起来即可。同样,我们可以运用类似的思路分析插入的字母对答案的影响。当插入 J 时,增加的贡献即为每个 O 后面 I 的出现次数的和(注意是每个),此时显然在最前面插入最优。同理,插入 I 时,增加的贡献即为每个 O 前面 J 的出现次数的和,在最后面插入最优。插入 O 时,则与最开始的计算方式相同。三种情况取最大值即可。时间复杂度 \(O(n)\)

#include <iostream>
#include <cstdio>
#define ll long long
#define N 200010

using namespace std;

int n,a[N];
ll c1,c2,c3,s1[N],s2[N],s3[N],ans,mx1,mx2,mx3;
string s;

int main()
{
	ios::sync_with_stdio( false );
	cin.tie( 0 );
	cout.tie( 0 ); 
	cin >> n;
	cin >> s;
	for( int i = 1 ; i <= n ; i ++ )
	{
		if( s[i - 1] == 'J' ) a[i] = 1;
		if( s[i - 1] == 'O' ) a[i] = 2;
		if( s[i - 1] == 'I' ) a[i] = 3,c3 ++;
	}
	for( int i = 1 ; i <= n ; i ++ )
	{
		if( a[i] == 1 ) c1 ++;
		if( a[i] == 3 ) c3 --;
		if( a[i] == 2 )
		{
			s1[i] = c1;
			s3[i] = c3;
			ans += c1 * c3;
		}
        mx2 = max( mx2 , c1 * c3 );
	}
	for( int i = 1 ; i <= n + 1 ; i ++ )
		s1[i] += s1[i - 1],mx1 = max( mx1 , s1[i] );
	for( int i = n + 1 ; i >= 1 ; i -- )
		s3[i] += s3[i + 1],mx3 = max( mx3 , s3[i] );
	cout << ans + max( max( mx1 , mx3 ) , mx2 );
	return 0;
}
posted @ 2025-09-12 08:07  FormulaOne  阅读(5)  评论(0)    收藏  举报