ABC.173.E - Multiplication 4

ABC.173.E - Multiplication 4

傳送門

題意:求最大子序列乘積。

思路:貪心,先對數組排序,討論kk的奇偶性,再兩個兩個地取。因爲兩個負數和兩個正數的乘積都是正數。

1.k1.k是奇數,我們先去最大的數作爲初始答案,然後特判一下最大數是否爲負數,

如果最大的數都爲負數,且kk是奇數,顯然答案只能爲負,這時我們取較小的正數是最優的,若初始答案爲正數,我們就貪心取分別設置兩個指針,從左邊和右邊,貪心地取,誰大取誰即可。

2.kk是偶數同理,直接開始從左邊和右邊貪心地取,這樣肯定保證取kk個。

此處貪心是可以把0的情況計算的。

ep:1,0,2,3,5ep:-1,0,2,3,5。 因爲我們排序後負數始終在00後面。

所以1×0<2×3-1\times 0< 2\times 3。 也滿足情況。

特殊情況2:1,1,2,3k=3-1,1,2,3。k=3也是滿足的,因爲1×1<1×2-1\times 1<1\times 2

需要注意的時乘的時候要取模,避免爆long longlong\ long

時間複雜度 :O(nlogn)O(nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
ll a[N];
int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%lld",&a[i]);
	sort(a,a+n);
	int l=0,r=n-1,w=1; 
	ll ans=1;
	if(k&1) ans=a[r--],k--,w=(ans<0?-1:1);
	while(k){
		ll x=a[l]*a[l+1],y=a[r]*a[r-1];
		if(x*w>y*w) ans=(ans*(x%mod))%mod,l+=2;
		else ans=(ans*(y%mod))%mod,r-=2;
		k-=2;
	}
	printf("%lld\n",(ans%mod+mod)%mod);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章