AT_arc174_a [ARC174A] A Multiply 題解

whrwlx發表於2024-03-26

題目翻譯

給你一個長度為 \(N\) 的整數序列, \(A=(A_1,A_2,…,A_N)\) ,和一個整數 \(C\)

在執行以下操作最多一次後,找出A中元素的最大可能和:

選擇兩個整數 \(l\)\(r\)\(1≤l≤r≤N\) ),

\(A_l,A_{l+1},…,A_r\) 分別乘以 \(C\)

演算法

法一(暴力)

可以 \(O_{(N^2)}\) 暴力列舉 \(l\)\(r\)

法二(正解)

前置知識:最大子段和

參考該題思路,我們可以求出最大子段和,來最大化 \(C\) 乘上的區間和

程式碼如下:

#include<bits/stdc++.h>
#define int long long
#define fd(i,a,b) for(int i=a;i<=b;i=-~i)
using namespace std;
int n,c,a[300100],f[300100],sum[300100],maxx=-1e6,ans=0;
signed main()
{
	ios::sync_with_stdio(0);
	cin>>n>>c;
	fd(i,1,n) cin>>a[i],sum[i]=sum[i-1]+a[i],maxx=max(a[i],maxx);
	//字首和
	if(c>0&&maxx<0)//全負且c>0
	{
		cout<<sum[n];
		return 0;
	}
	if(c<=0)
	{
		fd(i,1,n) a[i]=-a[i];//將C<=0的情況轉化為c>0的情況
	}
	fd(i,1,n)
	{
		if(i==1) f[i]=a[i];
		else f[i]=max(a[i],f[i-1]+a[i]);
		ans=max(ans,f[i]);
	}
	if(c>0) cout<<sum[n]+ans*(c-1);
	else cout<<sum[n]+ans*(1-c);
	//這裡減一是因為sum[n]已經加過一次了
	return 0;
}

無關的話(稽核大大,求過審):被禁言了,怎麼解啊?

感謝觀看!