Problem:


Score : 500 points

Problem Statement

Given are N integers A_1,\ldots,A_N.

We will choose exactly K of these elements. Find the maximum possible product of the chosen elements.

Then, print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Constraints

1 \leq K \leq N \leq 2\times 10^5

|A_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N K
A_1 \ldots A_N

Output

Print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Sample Input 1

4 2
1 2 -3 -4

Sample Output 1

12

The possible products of the two chosen elements are 2, -3, -4, -6, -8, and 12, so the maximum product is 12.

Sample Input 2

4 3
-1 -2 -3 -4

Sample Output 2

1000000001

The possible products of the three chosen elements are -24, -12, -8, and -6, so the maximum product is -6.

We print this value modulo (10^9+7), that is, 1000000001.

Sample Input 3

2 1
-1 1000000000

Sample Output 3

1000000000

The possible products of the one chosen element are -1 and 1000000000, so the maximum product is 1000000000.

Sample Input 4

10 10
1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1

Sample Output 4

999983200

Be sure to print the product modulo (10^9+7).



Sample input:
4 2
1 2 -3 -4


Sample output:
12

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
"""
Created on Sun Jul  5 21:49:24 2020

@author: NEC-PCuser
"""

N, K = map(int, input().split())

A = list(map(int, input().split()))

A.sort()

minus_list = []
plus_list = []
for i in range(len(A)):
    if (A[i] <= 0):
        minus_list.append(A[i])
    else:
        plus_list.append(A[i])

ans = 1
mod = 10 ** 9 + 7   
if N == K:
    for i in A:
        ans = (ans * i) % mod
elif 0 == len(plus_list) and  K % 2 == 1:
    minus_list.sort(reverse=True)
    for i in range(K):
        ans = (ans * minus_list[i]) % mod
else:
    minus_list.sort(reverse=True)
    plus_list.sort()
    if K % 2 == 1:
        ans = plus_list.pop()
    for i in range(K // 2):
        if (len(plus_list) < 2):
            ans = (minus_list.pop() * ans) % mod
            ans = (minus_list.pop() * ans) % mod
        elif (len(minus_list) < 2):
            ans = (plus_list.pop() * ans) % mod
            ans = (plus_list.pop() * ans) % mod
        elif (plus_list[len(plus_list) - 1] * plus_list[len(plus_list) - 2] > minus_list[len(minus_list) - 1] * minus_list[len(minus_list) - 2]):
            ans = (plus_list.pop()* ans) % mod
            ans = (plus_list.pop() * ans) % mod
        else:
            ans = (minus_list.pop() * ans) % mod
            ans = (minus_list.pop()* ans) % mod
print(ans)

Submission status: Accepted

Solution code:
n, k = map(int, input().split())
A = list(map(int, input().split()))

MOD = 10 ** 9 + 7

AA = sorted(A, key=lambda x: -abs(x))

nega1 = []
posi1 = []
for a in AA[:k]:
  if a < 0:
    nega1.append(a)
  else:
    posi1.append(a)

nega2 = []
posi2 = []
for a in AA[k:]:
  if a < 0:
    nega2.append(a)
  else:
    posi2.append(a)

if all(a < 0 for a in A) and k % 2 == 1:
  AA = sorted(A, key=lambda x: abs(x))
  nega1 = []
  posi1 = []
  for a in AA[:k]:
    nega1.append(a)

elif n == k:
  pass

elif len(nega1) % 2 != 0:
  if posi1 and nega2 and posi2:
    if abs(nega1[-1] * nega2[0]) < abs(posi1[-1] * posi2[0]):
      del nega1[-1]
      nega1.append(posi2[0])
    else:
      del posi1[-1]
      posi1.append(nega2[0])
  elif not posi1 or not nega2:
    del nega1[-1]
    nega1.append(posi2[0])
  elif not posi2:
    del posi1[-1]
    posi1.append(nega2[0])
  
a = 1
for m in posi1:
  a = (a * m) % MOD
for p in nega1:
  a = (a * p) % MOD
 
print(a)

Submission status: Accepted

Solution code:
# E - Multiplication 4
import heapq
N, K = map(int, input().split())
A = list(int(a) for a in input().split())
MOD = 10**9 + 7


if N == K:
    ans = 1
    for a in A:
        ans = (ans * a) % MOD
else:
    pos = []
    neg = []
    for a in A:
        if a >= 0:
            pos.append(a)
        else:
            neg.append(a)

    if len(neg) == N and K&1 == 1:
        neg.sort(reverse=True)
        ans = 1
        for i in range(K):
            ans = (ans * neg[i]) % MOD
    else:
        pos.sort(reverse=True)
        dbl = []
        ans = 1
        ini = 0
        rem = K
        if K&1 == 1:
            ans = (ans * pos[0]) % MOD
            ini = 1
            rem -= 1
        for i in range(0, (len(pos)-ini)//2):
            heapq.heappush(dbl, (pos[ini+i*2] * pos[ini+i*2+1])*-1)
        neg.sort()
        for i in range(0, len(neg)//2):
            heapq.heappush(dbl, (neg[i*2] * neg[i*2+1]) * -1)
        while rem > 0:
            ans = (ans * heapq.heappop(dbl) * -1) % MOD
            rem -= 2

print(ans)

Submission status: Accepted

Solution code:
# E - Multiplication 4
import heapq
N, K = map(int, input().split())
A = list(int(a) for a in input().split())
MOD = 10**9 + 7

# N = K の時
if N == K:
    ans = 1
    for a in A:
        ans = (ans * a) % MOD

else:
    pos = []
    neg = []
    for a in A:
        if a >= 0:
            pos.append(a)
        else:
            neg.append(a)

    # 必ずマイナスになる時＝全てがマイナスの値であり、
    # かつKが奇数の時
    if len(neg) == N and K&1 == 1:
        neg.sort(reverse=True)
        ans = 1
        for i in range(K):
            ans = (ans * neg[i]) % MOD

    # それ以外のプラスになるケース
    # プラスの要素とマイナスの要素を絶対値の大きい順にソートし、
    # Kが奇数であれば、プラスのリストから1つ選び、
    # 残りの偶数個のKに対して、２つずつを選んだ時の
    # 大きい方から取得していく
    else:
        pos.sort(reverse=True)
        pos2 = []
        ans = 1
        ini = 0
        rem = K
        if K&1 == 1:
            ans = (ans * pos[0]) % MOD
            ini = 1
            rem -= 1
        for i in range(0, (len(pos)-ini)//2):
            heapq.heappush(pos2, (pos[i*2+ini] * pos[i*2+ini+1])*-1)
        neg.sort()
        neg2 = []
        for i in range(0, len(neg)//2):
            heapq.heappush(neg2, (neg[i*2] * neg[i*2+1]) * -1)
        while rem > 0:
            if (pos2 != [] and neg2 == []) or (pos2 != [] and neg2 != [] and pos2[0] <= neg2[0]):
                tmp = heapq.heappop(pos2) * -1
            else:
                tmp = heapq.heappop(neg2) * -1
            ans = (ans * tmp) % MOD
            rem -= 2

print(ans)

Submission status: Accepted

Solution code:
MOD = (10 ** 9) + 7
n, k  = map(int, input().split())
a = list(map(int, input().split()))
 
negs = [-x for x in a if x < 0]
non_negs = [x for x in a if x >= 0]
 
if len(non_negs) == 0 and k % 2 == 1:
    negs.sort()
    ans = 1
    for i in range(k):
        ans = ans * -negs[i] % MOD
    print(ans)
    exit()
 
negs_p, non_negs_p = 0, 0
 
negs.sort(reverse = True)
non_negs.sort(reverse = True)
 
for i in range(k):
    if negs_p == len(negs):
        non_negs_p += 1
    elif non_negs_p == len(non_negs):
        negs_p += 1
    elif negs[negs_p] > non_negs[non_negs_p]:
        negs_p += 1
    else:
        non_negs_p += 1
 
if negs_p % 2 == 0 or k == n:
    ans = 1
    for i in range(negs_p):
        ans = ans * -negs[i] % MOD
    for i in range(non_negs_p):
        ans = ans * non_negs[i] % MOD
    print(ans)
    exit()
 
if negs_p == len(negs) or non_negs_p == 0:
    negs_p -= 1
    non_negs_p += 1
    ans = 1
    for i in range(negs_p):
        ans = ans * -negs[i] % MOD
    for i in range(non_negs_p):
        ans = ans * non_negs[i] % MOD
    print(ans)
    exit()
 
if non_negs_p == len(non_negs) or negs_p == 0:
    negs_p += 1
    non_negs_p -= 1
    ans = 1
    for i in range(negs_p):
        ans = ans * -negs[i] % MOD
    for i in range(non_negs_p):
        ans = ans * non_negs[i] % MOD
    print(ans)
    exit()
 
 
a = negs[negs_p - 1]
b = negs[negs_p]
c = non_negs[non_negs_p - 1]
d = non_negs[non_negs_p]
 
if a * b > c * d:
    negs_p += 1
    non_negs_p -= 1
else:
    negs_p -= 1
    non_negs_p += 1
 
ans = 1
for i in range(negs_p):
    ans = ans * -negs[i] % MOD
for i in range(non_negs_p):
    ans = ans * non_negs[i] % MOD
print(ans)

Submission status: Accepted

Solution code:
from decimal import *

n,k = map(int,input().split())
a = list(map(int,input().split()))
MOD = 10**9 + 7

ze = []
pl,mi = [],[]
for i in range(n):
    if a[i] < 0:
        ze.append((-a[i],1))
        mi.append(a[i])
    else:
        ze.append((a[i],0))
        pl.append(a[i])
        
ze.sort(reverse = True)
pl.sort(reverse = True)
mi.sort()

one = 0
for i in range(k):
    one += ze[i][1]
    
ans = 1
zero = k-one

if one % 2 == 0:
    for i in range(k):
        ans = ans * ze[i][0] % MOD
    print(ans)
        
elif len(pl) == 0:
    for i in range(k):
        ans = ans * mi[n-1-i] % MOD
    print(ans)
        
else:
    if (zero == len(pl) and one == len(mi)) or len(pl) == 0 or len(mi) == 0:
        ak = [zero,one]
    elif (zero != len(pl) and one == len(mi)) or zero == 0:
        ak = [zero+1,one-1]
    elif zero == len(pl) and one != len(mi) or one == 0:
        ak = [zero-1,one+1]
    else:
        if Decimal(abs(mi[one]))/Decimal(pl[zero-1]) >= Decimal(pl[zero])/Decimal(abs(mi[one-1])):
            ak = [zero-1,one+1]
        else:
            ak = [zero+1,one-1]
            
    ans = 1
    for i in range(ak[0]):
        ans = ans * pl[i] % MOD
    for i in range(ak[1]):
        ans = ans * mi[i] % MOD
        
    print(ans)

Submission status: Accepted

Solution code:
n,k=map(int, input().split())
a = list(map(int, input().split()))
mod=10**9+7
if n==k:
    ans=1
    for i in range(k):
        ans*=a[i]
        ans%=mod
    print(ans)
    exit()
minus=[i for i in a if i<0]
plus=[i for i in a if i>=0]
from collections import deque
minus=deque(sorted(minus))
plus=deque(sorted(plus,reverse=True))

n_minus=len(minus)
n_plus=len(plus)

if n_minus==n:
    ans=1
    if k%2==0:
        for i in range(k):
            ans*=minus.popleft()
            ans+=mod
            ans%=mod
        print(ans)
        exit()
    else:
        for i in range(k):
            ans*=minus.pop()
            ans+=mod
            ans%=mod
        print(ans)
        exit()

cnt_minus=0
cand=deque([])
for i in range(k):
    if not plus or ((plus and minus) and abs(minus[0])>abs(plus[0])):
        cand.append(minus.popleft())
        cnt_minus+=1
    elif not minus or ((plus and minus) and abs(minus[0])<abs(plus[0])):
        cand.append(plus.popleft())
    else:
        if cnt_minus%2==1:
            cand.append(minus.popleft())
            cnt_minus+=1
        else:
            cand.append(plus.popleft())

if cnt_minus%2==0:
    ans=1
    for i in range(k):
        ans*=cand[i]
        ans+=mod
        ans%=mod
    print(ans)
    exit()

if 0 in cand:
    print(0)
    exit()

tmpm,tmpp=None,None

for i in range(k-1,-1,-1):
    if cand[i]<0 and tmpm==None:
        tmpm=cand[i]
    elif cand[i]>=0 and tmpp==None:
        tmpp=cand[i]

#print(tmpm,tmpp)
cand1,cand2=None,None
if tmpm!=None and plus:
    cand1=plus[0]/abs(tmpm)
if tmpp!=None and minus:
    if tmpp!=0:
        cand2=abs(minus[0])/abs(tmpp)
    else:
        cand2=0

if tmpp==0:
    if minus:
        ans=1
        flg=True
        for i in range(k):
            if flg and cand[i]==tmpp:
                flg=False
                continue
            ans*=cand[i]
            ans+=mod
            ans%=mod
        print((ans*minus[0])%mod)
        exit()
elif (cand1!=None and cand2==None) or ((cand1!=None and cand2!=None) and plus[0]*abs(tmpp)>=abs(minus[0]*tmpm)):
    ans=1
    flg=True
    for i in range(k):
        if flg and cand[i]==tmpm:
            flg=False
            continue
        ans*=cand[i]
        ans+=mod
        ans%=mod
    print((ans*plus[0])%mod)
    exit()

elif (cand1==None and cand2!=None) or ((cand1!=None and cand2!=None) and plus[0]*abs(tmpp)<abs(minus[0]*tmpm)):
    ans=1
    flg=True
    for i in range(k):
        if flg and cand[i]==tmpp:
            flg=False
            continue
        ans*=cand[i]
        ans+=mod
        ans%=mod
    print((ans*minus[0])%mod)
    exit()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

def main():
    N, K = map(int, input().split())
    A = list(map(int, input().split()))

    MOD = 10 ** 9 + 7

    pos = []
    neg = []
    for a in A:
        if a >= 0:
            pos.append(a)
        else:
            neg.append(a)

    flag = False  # 積を正にできるか

    if N == K:
        ans = 1
        for a in A:
            ans *= a
            ans %= MOD
            
        print(ans % MOD)
        exit()


    if len(pos) > 0:
        flag = True
    else:
        if K % 2 == 0:
            flag = True

    ans = 1
    if not flag:
        # 積を正にできないとき
        # 絶対値の小さい方からK個とる
        A = sorted([abs(x) for x in A])
        for a in A[:K]:
            ans *= a
            ans %= MOD
        ans *= -1
    else:
        pos = sorted(pos)
        neg = sorted(neg, reverse=True)
        if K % 2 == 1:
            # Kが奇数の時
            # 一番大きい偶数を1つとる。
            ans *= pos.pop()
            ans %= MOD

        # pos, neg sort -> 2個ずつペア -> 降順sort -> 上から K//2 個とる
        pairs = []
        while len(pos) >= 2:
            x = pos.pop()
            x *= pos.pop()
            pairs.append(x)
        while len(neg) >= 2:
            x = neg.pop()
            x *= neg.pop()
            pairs.append(x)
        pairs = sorted(pairs, reverse=True)
        for p in pairs[: K // 2]:
            ans *= p
            ans %= MOD

    print(ans % MOD)

    
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
import heapq

input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    N, K = map(int, input().split())
    A = list(map(int, input().split()))

    MOD = 10 ** 9 + 7

    pos = []
    neg = []
    for a in A:
        if a >= 0:
            pos.append(a)
        else:
            neg.append(a)

    flag = False  # 積を正にできるか

    if N == K:
        ans = 1
        for a in A:
            ans *= a
            ans %= MOD
        print(ans % MOD)
        exit()

    if len(pos) > 0:
        flag = True
    else:
        if K % 2 == 0:
            flag = True

    ans = 1
    if not flag:
        # 積を正にできないとき
        # 絶対値の小さい方からK個とる
        h = [abs(x) for x in A]
        heapq.heapify(h)

        for i in range(K):
            ans *= heapq.heappop(h)
            ans %= MOD
        ans *= -1
    else:
        hpos = [-x for x in pos]
        heapq.heapify(hpos)
        hneg = neg[:]
        heapq.heapify(hneg)
        if K % 2 == 1:
            # Kが奇数の時
            # 一番大きい偶数を1つとる。
            ans *= -heapq.heappop(hpos)
            ans %= MOD

        # pos, neg sort -> 2個ずつペア -> 降順sort -> 上から K//2 個とる
        pairs = []
        while len(hpos) >= 2:
            x = -heapq.heappop(hpos)
            x *= -heapq.heappop(hpos)
            heapq.heappush(pairs, -x)
        while len(hneg) >= 2:
            x = heapq.heappop(hneg)
            x *= heapq.heappop(hneg)
            heapq.heappush(pairs, -x)
        if len(pairs):
            for i in range(K // 2):
                ans *= -heapq.heappop(pairs)
                ans %= MOD

    print(ans % MOD)


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
def resolve():
    n,k=map(int,input().split())
    a=sorted(list(map(int,input().split())))
    MOD=10**9+7
    ans=1
    if k==1:
        ans=a[-1]
    elif a[0]>=0 or (a[-1]<0 and k%2==1):
        for i in a[-k:]:
            ans=(ans*i)%MOD
    elif a[-1]<0 and k%2==0:
        for i in a[:k]:
            ans=(ans*i)%MOD
    else:
        ans=1
        if k%2==1 and n>=3:
            ans*=a[-1]
            ans%=MOD
            l,r=0,-2
            lm=a[0]*a[1]
            rm=a[-2]*a[-3]    
        else:
            l,r=0,-1
            lm=a[0]*a[1]
            rm=a[-1]*a[-2]
        for i in range(k//2):
            if lm>=rm:
                ans*=lm%MOD
                l+=2
                if l<=n-2:
                    lm=a[l]*a[l+1]
            else:
                ans*=rm%MOD
                r-=2
                if 1<=n+r:
                    rm=a[r]*a[r-1]
            ans%=MOD
    print(ans)

if __name__ == '__main__':
    resolve()

Submission status: Accepted

Solution code:
from collections import deque
 
N, K = map(int, input().split())
A = list(map(int, input().split()))
MOD = 10**9 + 7
 
P = [a for a in A if a >= 0]
N = [a for a in A if a < 0]
 
def canPositive():
    for i in range(0, len(N) + 1, 2):
        p = K - i
        if p < 0:
            break
        if len(P) >= p:
            return True
    return False

if not canPositive():
    A.sort(key=lambda a: abs(a))
    ans = 1
    for a in A[:K]:
        ans *= a
        ans %= MOD
    print(ans)
    exit()

if not P or not N or len(A) == K:
    A.sort(key=lambda a: abs(a), reverse=True)
    ans = 1
    for a in A[:K]:
        ans *= a
        ans %= MOD
    print(ans)
    exit()

P.sort(key=lambda a: abs(a))
N.sort(key=lambda a: abs(a))
P = deque(P)
N = deque(N)
 
ans = 1
sign = 1
while K > 0:
    ans %= MOD
    if ans == 0:
        break
    if K == 1:
        if sign < 0:
            ans *= N.pop()
        else:
            ans *= P.pop()
        break
 
    if len(P) >= 2 and len(N) >= 2:
        p = P[-1] * P[-2]
        n = N[-1] * N[-2]
        if p > n:
            ans *= P.pop()
            K -= 1
        else:
            ans *= N.pop() * N.pop()
            K -= 2
        continue
    if len(P) <= 1 or len(N) <= 1:
        if len(N) == 0:
            ans *= P.pop()
            K -= 1
            continue
 
        if len(P) == 0:
            ans *= N.pop()
            K -= 1
            sign *= -1
            continue
 
        if len(N) == 1:
            n = N.pop()
            if sign < 0:
                ans *= n
                K -= 1
                sign *= -1
            continue
 
        if len(P) == 1:
            p = P.pop()
            if K % 2 == 1 and sign > 0 or K % 2 == 0 and sign < 0:
                ans *= p
                K -= 1
            continue

print(ans % MOD)

Submission status: Accepted

Solution code:
def get_neg(neg_list, k, mod):
    ans = 1
    neg_list.sort(reverse=True)
    for num in neg_list[:k]:
        ans = ans * num % mod
    return ans


def get_pos(pos_list, neg_list, k, mod):
    ans = 1
    nums = []
    neg_iter = iter(sorted(neg_list))
    pos_iter = iter(sorted(pos_list, reverse=True))
    if k % 2 == 1:
        ans *= pos_iter.__next__()
        k -= 1
        
    for a, b in zip(pos_iter, pos_iter):
        nums.append(a * b)

    for a, b in zip(neg_iter, neg_iter):
        nums.append(a * b)

    nums.sort(reverse=True)
    for num in nums[:k//2]:
        ans *= num
        ans %= mod
    return ans


def get_all(num_list, mod):
    ans = 1
    for num in num_list:
        ans = ans * num % mod
    return ans


def main():
    n, k = map(int, input().split())
    A = list(map(int, input().split()))
    mod = 10 ** 9 + 7
    
    if n == k:
        ans = get_all(A, mod)
        print(ans)
        return
    
    pos_list = []
    neg_list = []

    for a in A:
        if a >= 0:
            pos_list.append(a)
        else:
            neg_list.append(a)

    if k % 2 and not pos_list:
        ans = get_neg(neg_list, k, mod)
    else:
        ans = get_pos(pos_list, neg_list, k, mod)

    print(ans)


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
n, k = map(int, input().split())
a = list(map(int, input().split()))
mod = 10 ** 9 + 7

mia = sorted([i for i in a if i < 0], reverse=True)
pla = sorted([i for i in a if i >= 0])

cnt = 1
if len(pla) == 0 and k % 2 == 1:
    for i in mia[:k]:
        cnt = cnt * i % mod
    print(cnt)
    exit()

while k > 0:
    if k == 1 or len(mia) <= 1:
        if len(pla) == 0:
            cnt *= mia.pop()
        elif len(pla) > 0:
            cnt *= pla.pop()
        k -= 1
    elif len(pla) <= 1:
        cnt *= mia.pop() * mia.pop()
        k -= 2
    elif pla[-1] * pla[-2] > mia[-1] * mia[-2]:
        cnt *= pla.pop()
        k -= 1
    elif pla[-1] * pla[-2] <= mia[-1] * mia[-2]:
        cnt *= mia.pop() * mia.pop()
        k -= 2
    cnt %= mod
else:
    print(cnt)

Submission status: Accepted

Solution code:
n, k = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
ans = 1
mod = 10**9 + 7
c = 0
z = 0
for i in a:
    if i < 0:
        c += 1
    elif i == 0:
        z += 1
if c == n and k & 1:
    a.reverse()
    for i in range(k):
        ans *= -a[i]
        ans %= mod
    print(-ans % mod)
elif c == n:
    for i in range(k):
        ans *= -a[i]
        ans %= mod
    print(ans)
elif k == n:
    for i in a:
        ans *= abs(i)
        ans %= mod
    print(((-1)**(c & 1) * ans) % mod)
else:
    plus = [i for i in a if i > 0]
    minus = [i for i in a if i <= 0]
    plus.sort(reverse=1)
    minus.sort()
    plus += [0] * z
    x = len(plus)
    y = len(minus)
    p, m = 0, 0
    if k & 1:
        ans *= plus[0]
        p += 1
    for i in range(k // 2):
        if x - 1 <= p:
            ans *= minus[m] * minus[m + 1]
            m += 2
        elif y - 1 <= m:
            ans *= plus[p] * plus[p + 1]
            p += 2
        else:
            if minus[m] * minus[m + 1] >= plus[p] * plus[p + 1]:
                ans *= minus[m] * minus[m + 1]
                m += 2
            else:
                ans *= plus[p] * plus[p + 1]
                p += 2
        ans %= mod

    print(ans % mod)

Submission status: Accepted

Solution code:
# Contest No.: ABC173
# Problem No.: E
# Solver:      JEMINI
# Date:        20200705

import sys
import heapq

def main():
    modVal = 10 ** 9 + 7
    # parsing
    n, k = map(int, sys.stdin.readline().split())
    nums = list(map(int, sys.stdin.readline().split()))
    
    # edge case; n == k
    if n == k:
        ans = 1
        for i in nums:
            ans *= i % modVal
            ans %= modVal
        print(ans % modVal)
        return
    
    # edge case; all neg
    if max(nums) < 0:
        nums.sort()
        ans = 1
        # odd k
        if k % 2:
            for i in range(k):
                ans *= nums[-i - 1] % modVal
                ans %= modVal
        # even k
        else:
            for i in range(k):
                ans *= nums[i] % modVal
                ans %= modVal
        print(ans % modVal)
        return
    
    # convert to absolute value & count zeros
    absNums = []
    zeroCnt = 0
    for i in nums:
        if i == 0:
            zeroCnt += 1
        else:
            absNums.append([abs(i), i])
    absNums.sort()  # sorted by absolute value
    
    # edge case; non-zero cnt is less than k
    if len(absNums) < k:
        print(0)
        return

    # separate non-zero int to 4 sorted lists; all values are absolute value
    posOverK = []
    negOverK = []
    posLessK = []
    negLessK = []
    for _ in range(k):
        temp = absNums.pop()
        if temp[1] > 0:
            posOverK.append(temp[0])
        else:
            negOverK.append(temp[0])
    while absNums:
        temp = absNums.pop()
        if temp[1] > 0:
            posLessK.append(temp[0])
        else:
            negLessK.append(temp[0])

    posOverK.sort()
    negOverK.sort()
    posLessK.sort()
    negLessK.sort()
    
    # odd negative numbers; if able, change to even
    if len(negOverK) % 2:
        minNeg = None
        minPos = None
        maxNeg = None
        maxPos = None
        if posOverK:
            minPos = posOverK[0]
        if negOverK:
            minNeg = negOverK[0]
        if posLessK:
            maxPos = posLessK[-1]
        if negLessK:
            maxNeg = negLessK[-1]
        
        # both case available; pos -> neg or neg -> pos
        if (minNeg and maxPos) and (minPos and maxNeg):
            # compare ratio
            if maxPos * minPos > maxNeg * minNeg:
                negOverK[0] = maxPos
            else:
                posOverK[0] = maxNeg
        # one case available
        elif not (minNeg and maxPos) and (minPos and maxNeg):
            posOverK[0] = maxNeg
        elif (minNeg and maxPos) and not (minPos and maxNeg):
            negOverK[0] = maxPos
        # unchangable, zero exists
        elif zeroCnt > 0:
            print(0)
            return
    
    # answer building
    ans = 1
    for i in posOverK:
        ans *= i % modVal
        ans = ans % modVal
    for i in negOverK:
        ans *= i % modVal
        ans = ans % modVal
    
    print(ans % modVal)
    return

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
from collections import deque

N, K = map(int, input().split())
A = list(map(int, input().split()))
MOD = 10**9 + 7
A.sort(reverse=True)

ans = 1
B = deque(A)

if K % 2 == 1:
    ans *= B.popleft()

for _ in range(K // 2):
    l = B[0] * B[1]
    r = B[-1] * B[-2]
    if l >= r:
        ans *= B.popleft() * B.popleft()
    else:
        ans *= B.pop() * B.pop()
    if ans > 0: ans %= MOD
    else: ans = (ans % MOD) - MOD

if ans < 0:
    ans = 1
    for a in A[:K]:
        ans *= a
        ans %= MOD

print(ans % MOD)

Submission status: Accepted

Solution code:
mod=10**9+7
n,k=map(int,input().split())
arr=list(map(int,input().split()))
cnt_plus=0
cnt_zero=0
cnt_minus=0
arr_plus=[]
arr_minus=[]

for i in range(n):
    if arr[i]>0:
        cnt_plus+=1
        arr_plus.append(arr[i])
    elif arr[i]<0:
        cnt_minus+=1
        arr_minus.append(-arr[i])
    else:
        cnt_zero+=1
if cnt_plus+cnt_minus<k: #K個の積の中に0を含む場合、答えは0
    print(0)
    exit()
    
if k==n: #K=Nの場合
    if cnt_zero!=0: #0がひとつでもあれば答えは0
        print(0)
    else:
        ans=1
        for i in range(cnt_plus):
            ans*=arr_plus[i]
            ans%=mod
        for i in range(cnt_minus):
            ans*=arr_minus[i]
            ans%=mod
        if cnt_minus%2==0: #負の数が偶数個であれば積は正
            print(ans)
        else: #そうでなければ積は負となる
            print((-ans)%mod)
    exit()
if cnt_plus==0 and k%2==1: #正の数がないとき
    if cnt_zero!=0: #0がひとつでもあれば答えは0にできる
        print(0)
    else: #0がないときは負の数を絶対値が小さい順に掛けるのが最善
        arr_minus=sorted(arr_minus)
        tmp=1
        for i in range(k):
            tmp*=arr_minus[i]
            tmp%=mod
        print((-tmp)%mod)
    exit()
else: #正の数と負の数から合計K個取れるとき
    arr_plus=sorted(arr_plus,reverse=True)
    arr_minus=sorted(arr_minus,reverse=True)
    if k%2==0: #Kが偶数であれば何もしない
        ans=1
        pos_plus=0
        pos_minus=0
        cnt=0
    else: #Kが奇数であれば正の数から最大のものを取っておき、Kが偶数の場合に帰着させる
        ans=arr_plus[0]
        pos_plus=1
        pos_minus=0
        cnt=1
    while cnt<k:
        cand1=0
        if pos_plus<=cnt_plus-2: #正の数を2つ取れるなら取る
            cand1=arr_plus[pos_plus]*arr_plus[pos_plus+1]      
            cand2=0
        if pos_minus<=cnt_minus-2: #負の数を2つ取れるなら取る:
            cand2=arr_minus[pos_minus]*arr_minus[pos_minus+1]
        if cand1>=cand2: #正の数を2つ取った積のほうが大きい場合
            pos_plus+=2
            ans*=cand1
            ans%=mod
        else: #負の数を2つ取った積のほうが大きい場合
            pos_minus+=2
            ans*=cand2
            ans%=mod
        cnt+=2
    print(ans)
    exit()

Submission status: Accepted

Solution code:
n,k=map(int, input().split())
*a,=map(int, input().split())

ans=1
mod=10**9+7

a.sort()
if a[0]>=0:
    for i in range(n-1,n-k-1,-1):
        ans*=a[i]
        ans%=mod
    print(ans)
    exit()
if a[-1]<=0:
    if k%2:
        for i in range(n-1,n-k-1,-1):
            ans*=a[i]
            ans%=mod
    else:
        for i in range(k):
            ans*=a[i]
            ans%=mod
    print(ans)
    exit()
l=0;r=n-1
if k%2:
    ans=a[-1]
    r-=1
    k-=1
while k:
    if a[l]*a[l+1]>a[r]*a[r-1]:
        ans*=a[l]*a[l+1]
        l+=2
    else:
        ans*=a[r]*a[r-1]
        r-=2
    k-=2
    ans%=mod
   
print(ans)

Submission status: Accepted

Solution code:
n,k,*a=map(int,open(0).read().split())
a.sort()
mod=10**9+7
ans=1
i=0
j=-1
kk=k
while kk>1:
    if a[i]*a[i+1]>a[j]*a[j-1]:
        ans=ans*a[i]*a[i+1]%mod
        i+=2
        kk-=2
    else:
        ans=ans*a[j]%mod
        j-=1
        kk-=1
if kk==1:
    ans=ans*a[j]%mod

if a[-1]<0 and k%2==1:
    ans=1
    for i in a[n-k:]:
        ans=ans*i%mod
print(ans)

Submission status: Accepted

Solution code:
n, k = map(int, input().split())
A = list(map(int, input().split()))

mod = 10 ** 9 + 7
negs = [-x for x in A if x < 0]
non_negs = [x for x in A if x >= 0]


def inv(a):
    return pow(a, mod - 2, mod)


# 負の数を選ばざるを得ない数を考える
# 選べる負の数の個数の最小
n_min = k - (max(n - len(negs), 0))
# 　選べる負の数の個数の最大
n_max = min(n, k)

# この2数が一致していて、更に奇数のときにのみ負になる。(はず)
if n_max == n_min and n_max % 2 == 1:
    negs.sort()
    non_negs.sort()
    cnt = 0
    ans = 1
    n_idx, nn_idx = 0, 0
    while cnt < k:
        if n_idx == len(negs):
            ans *= non_negs[nn_idx]
            nn_idx += 1
        elif nn_idx == len(non_negs):
            ans *= -negs[n_idx]
            n_idx += 1
        else:
            if non_negs[nn_idx] < negs[n_idx]:
                ans *= non_negs[nn_idx]
                nn_idx += 1
            else:
                ans *= -negs[n_idx]
                n_idx += 1
        ans %= mod
        cnt += 1

    print(ans % mod)
    exit()

negs.sort(reverse=True)
non_negs.sort(reverse=True)

cnt = 0
ans = 1
neg_cnt = 0
n_idx, nn_idx = 0, 0
# idx番号と配列の長さを比較して、その配列から取得可能かをみる
while cnt < k:
    if n_idx == len(negs):
        ans *= non_negs[nn_idx]
        nn_idx += 1
    elif nn_idx == len(non_negs):
        ans *= -negs[n_idx]
        n_idx += 1
        neg_cnt += 1
    else:
        if non_negs[nn_idx] > negs[n_idx]:
            ans *= non_negs[nn_idx]
            nn_idx += 1
        else:
            ans *= -negs[n_idx]
            n_idx += 1
            neg_cnt += 1
    ans %= mod
    cnt += 1

# 動かす余地がない場合→negが偶数個or動かす余裕がない
if neg_cnt % 2 == 0 or n == k:
    # REからここがおかしそう…
    print(ans % mod)
    exit()
else:
    # 次にかけるのはnegs[n_idx] or non_negs[nn_idx]
    # 一つ戻すならnegs[n_idx-1] or non_negs[nn_idx-1]

    # negsが右にずらせるかどうか
    if n_idx == len(negs) or nn_idx == 0:
        ans *= inv(-negs[n_idx - 1])
        ans *= non_negs[nn_idx]
        ans %= mod
    # non_negsが右にずらせるか
    elif nn_idx == len(non_negs) or n_idx == 0:
        ans *= inv(non_negs[nn_idx - 1])
        ans *= -negs[n_idx]
        ans %= mod
    else:
        # 両方ともずらせないのはすでに除外済み(のはず)
        if non_negs[nn_idx] * non_negs[nn_idx - 1] > negs[n_idx] * negs[n_idx - 1]:
            ans *= non_negs[nn_idx]
            ans *= inv(-negs[n_idx - 1])
            ans %= mod
        else:
            ans *= -negs[n_idx]
            ans *= inv(non_negs[nn_idx - 1])
            ans %= mod

    print(ans % mod)
    exit()