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).

Solution in Java (OpenJDK 11.0.6) (judge verdict: Runtime Error)

import java.util.*;		
import java.util.function.Function;
import java.util.stream.Collectors;
import java.io.*;
import java.math.*;
public class Main{
	static public void main(String args[])throws IOException{
		int tt=1;
		StringBuilder sb=new StringBuilder();
		for(int ttt=1;ttt<=tt;ttt++){
			int n=i();
			int k=i();
			long[] a=new long[n];
			int zero=0;
			ArrayList<Long> neg=new ArrayList<>();
			ArrayList<Long> pos=new ArrayList<>();
			for(int i=0;i<n;i++){
				a[i]=l();
				if(a[i]<0){
					neg.add(-a[i]);
				}else if(a[i]>0){
					pos.add(a[i]);
				}else if(a[i]==0){
					zero++;
				}
			}
			Collections.sort(neg);
			Collections.sort(pos);
			if(n-zero<k){
				pln("0");
			}else{
				long max=Long.MIN_VALUE;
				if(zero>0){
					max=0;
				}
				if(neg.size()==0){
					if(pos.size()>=k){
						long ans=1;
						int count=0;
						for(int i=pos.size()-1;i>=0;i--){
							ans=(ans*pos.get(i))%mod;
							count++;
							if(count==k){
								break;
							}
						}
						max=ans;
					}else{
						max=0;
					}
				}else{
					if(pos.size()+(neg.size()/2)*2<k){
						if(zero>0){
							max=0;
						}else{
							long ans=1;
							for(int i=0;i<n;i++){
								ans=(ans*Math.abs(a[i]))%mod;
							}
							ans=(-ans+mod)%mod;
							ans=(ans+mod)%mod;
							max=ans;
						}
					}else if(pos.size()==0){
						if(k%2==0 && (neg.size()/2)*2>=k){
							long ans=1;
							int count=0;
							for(int i=neg.size()-1;i>=0;i--){
								ans=(ans*neg.get(i))%mod;
								count++;
								if(count==k){
									break;
								}
							}
						}else{
							if(zero>0){
								max=0;
							}else{
								long ans=1;
								int count=0;
								for(int i=0;i<k;i++){
									ans=(ans*neg.get(i))%mod;
									count++;
									if(count==k){
										break;
									}
								}
								ans=(-ans+mod+mod)%mod;
								ans=(ans+mod)%mod;
								max=ans;
							}
						}
					}else if(pos.size()+(neg.size()/2)*2>=k){
						int i=neg.size()-1;
						int j=pos.size()-1;
						long ans=1;
						int count=0;
						while(count<k){
							long tmp=0;
							if(i-1>=0){
								tmp=neg.get(i)*neg.get(i-1);
							}
							long tmp1=0;
							if(j-1>=0){
								tmp1=pos.get(j)*pos.get(j-1);
							}
							if(tmp>tmp1){
								if(count+2<=k){
									ans=(ans*tmp)%mod;
									count+=2;
									i=i-2;
								}else{
									ans=(ans*pos.get(j))%mod;
									count++;
									j=j-1;
								}
							}else if(tmp<tmp1){
								if(count+2<=k){
									ans=(ans*tmp1)%mod;
									count+=2;
									j=j-2;
								}else{
									ans=(ans*pos.get(j))%mod;
									count++;
									j=j-1;
								}
							}else if(tmp==tmp1){
								if(tmp==0){
									ans=(ans*pos.get(j))%mod;
									count++;
									j=j-1;
								}else{
									if(count+2<=k){
										ans=(ans*tmp1)%mod;
										count++;
										i=i-2;
									}else{
										ans=(ans*pos.get(j))%mod;
										j=j-1;
										count++;
									}
								}
							}
						}
						max=ans;
					}
				}
				pln(max+"");
			}
		}
		System.out.print(sb.toString());
	}
	static InputReader in=new InputReader(System.in);
	static OutputWriter out=new OutputWriter(System.out);
	static ArrayList<ArrayList<Integer>> graph;
	static int mod=1000000007;
	static class Pair{
		int x;
		int y;
		Pair(int x,int y){
			this.x=x;
			this.y=y;
		}
		/*@Override
		public int hashCode() 
		{ 
			final int temp = 14; 
			int ans = 1; 
			ans =x*31+y*13; 
			return (int)ans;
		}
       @Override
        public boolean equals(Object o) 
        { 
            if (this == o) { 
                return true; 
            } 
            if (o == null) { 
                return false; 
            } 
            if (this.getClass() != o.getClass()) { 
                return false; 
            } 
            Pair other = (Pair)o; 
            if (this.x != other.x || this.y!=other.y) { 
                return false; 
            } 
            return true; 
        }*/
	}
	public static int[] sort(int[] a){
		int n=a.length;
		ArrayList<Integer> ar=new ArrayList<>();
		for(int i=0;i<a.length;i++){
			ar.add(a[i]);
		}
		Collections.sort(ar);
		for(int i=0;i<n;i++){
			a[i]=ar.get(i);
		}
		return a;
	}
	public static long pow(long a, long b){
        long result=1;
        while(b>0){
            if (b % 2 != 0){
                result=(result*a);
                b--;
            } 
            a=(a*a);
            b /= 2;
        }   
        return result;
    }
	public static long gcd(long a, long b){
        if (a == 0){
            return b;
		}
        return gcd(b%a, a);
    }
	public static long lcm(long a, long b){
		return a*(b/gcd(a,b));
	}
	public static long l(){
		String s=in.String();
		return Long.parseLong(s);
	}
	public static void pln(String value){
		System.out.println(value);
	}
	public static int i(){
		return in.Int();
	}
	public static String s(){
		return in.String();
	}
}
class InputReader 
{
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;
	public InputReader(InputStream stream) {
		this.stream = stream;
	}
	public int read() {
		if (numChars== -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	public int Int() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	public String String() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	} 
	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	} 
	public String next() {
		return String();
	} 
	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}
class OutputWriter {
	private final PrintWriter writer;
	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}
	public void print(Object...objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}
	public void printLine(Object...objects) {
		print(objects);
		writer.println();
	}
	public void close() {
		writer.close();
	}
	public void flush() {
		writer.flush();
	}
 }
class IOUtils {
	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.Int();
		return array;
	}
}