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 1.8.0) (judge verdict: Wrong Answer)

import java.io.*;
import java.util.*;

public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    static FastReader s = new FastReader();
    static PrintWriter out = new PrintWriter(System.out);

    private static int[] rai(int n) {
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = s.nextInt();
        }
        return arr;
    }

    private static int[][] rai(int n, int m) {
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = s.nextInt();
            }
        }
        return arr;
    }

    private static long[] ral(int n) {
        long[] arr = new long[n];
        for (int i = 0; i < n; i++) {
            arr[i] = s.nextLong();
        }
        return arr;
    }

    private static long[][] ral(int n, int m) {
        long[][] arr = new long[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = s.nextLong();
            }
        }
        return arr;
    }

    private static int ri() {
        return s.nextInt();
    }

    private static long rl() {
        return s.nextLong();
    }

    private static String rs() {
        return s.next();
    }
    static int gcd(int a,int b)
    {
        if(b==0)
        {
            return a;
        }
        return gcd(b,a%b);
    }


    static final int MAXN = 10000001;

    // stores smallest prime factor for every number
    static int spf[] = new int[MAXN];

    // Calculating SPF (Smallest Prime Factor) for every
    // number till MAXN.
    // Time Complexity : O(nloglogn)
    static void sieve()
    {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)

            // marking smallest prime factor for every
            // number to be itself.
            spf[i] = i;

        // separately marking spf for every even
        // number as 2
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;

        for (int i=3; i*i<MAXN; i++)
        {
            // checking if i is prime
            if (spf[i] == i)
            {
                // marking SPF for all numbers divisible by i
                for (int j=i*i; j<MAXN; j+=i)

                    // marking spf[j] if it is not
                    // previously marked
                    if (spf[j]==j)
                        spf[j] = i;
            }
        }
    }

    // A O(log n) function returning primefactorization
    // by dividing by smallest prime factor at every step
    static long getFactorization(int x)
    {
        Vector<Integer> ret = new Vector<>();
        while (x != 1)
        {
            ret.add(spf[x]);
            x = x / spf[x];
        }
        HashMap<Integer,Long> map=new HashMap<>();
        for(int i:ret)
        {
            map.put(i,map.getOrDefault(i,0L)+1L);
        }
        long prod=1L;
        for(int i:map.keySet())
        {
            prod*=map.get(i)+1L;
        }

        return prod;
    }
    public int kthFactor(int n, int k) {
        TreeSet<Integer> pq=new TreeSet<>();
        for(int i=1;i<=Math.sqrt(n);i++)
        {
            if(n%i==0)
            {
                pq.add(i);
                pq.add(n/i);
            }
        }
        if(pq.size()<k)
        {
            return -1;
        }
        else {
            List<Integer> list = new ArrayList<>(pq);
            return list.get(k-1);
        }
    }
    public int minNumberOfSemesters(int n, int[][] dependencies, int k) {
        HashMap<Integer,HashSet<Integer>> map=new HashMap<>();
        for(int i=1;i<=n;i++)
        {
            map.put(i,new HashSet<>());

        }
        for(int[] arr:dependencies)
        {
            map.get(arr[0]).add(arr[1]);
        }
        List<Integer> ans=new ArrayList<>();
        HashSet<Integer> visited=new HashSet<>();
        Stack<Integer> stack=new Stack<>();
        int res=Integer.MIN_VALUE;
        for(int i=1;i<=n;i++)
        {
            if(!visited.contains(i))
            {
                topoSort(i,map,visited,stack);
            }
        }

        while (!stack.empty())
            ans.add(stack.pop());

        // System.out.println(ans);

        HashMap<Integer,HashSet<Integer>> contains=new HashMap<>();
        for(int i=1;i<=n;i++)
        {
            contains.put(i,new HashSet<>());
        }
        HashMap<Integer,Integer> canReach=new HashMap<>();

        for(int i=1;i<=n;i++)
        {
            HashSet<Integer> vis=new HashSet<>();
            dfs(map,vis,i);
            vis.remove(i);
            for(int j:vis)
            {
                contains.get(j).add(i);
            }
            canReach.put(i,vis.size());

        }

        HashMap<Integer,Integer> in=new HashMap<>();
        int max=Integer.MIN_VALUE;
        for(int i=1;i<=n;i++)
        {
            in.put(i,contains.get(i).size());
            max=Math.max(max,in.get(i));
        }

        for(int i:in.keySet())
        {
            System.out.println(i+" -> "+in.get(i));
        }
        HashSet<Integer> done=new HashSet<>();
        int count=0;
        int curr=0;

        List<Integer> mid=new ArrayList<>();
        for(int i=0;i<=max;i++)
        {
            List<Integer> temp=new ArrayList<>();
            for(int j:ans)
            {
                if(in.get(j)==i)
                {
                    temp.add(j);
                }
            }
            temp.sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return canReach.get(o2)-canReach.get(o1);
                }
            });
            mid.addAll(temp);
        }
        ans=new ArrayList<>(mid);
        System.out.println("mid="+mid);
        while(done.size()<ans.size())
        {
            List<Integer> l=new ArrayList<>();
            for(int i:ans)
            {
                if(!done.contains(i))
                {
                    int flag=0;
                    for(int j:contains.get(i))
                    {
                        if(!done.contains(j))
                        {
                            flag=1;
                            break;
                        }
                    }
                    if(flag==0)
                    {
                        l.add(i);
                    }
                    if(l.size()==k)
                    {
                        break;
                    }
                }
            }
            if(l.size()>0)
            {
                count++;
                for(int i:l)
                {
                    done.add(i);
                }
            }
            System.out.println(done);

        }
        return count;
    }

    static void dfs(HashMap<Integer,HashSet<Integer>> map,HashSet<Integer> vis,int node)
    {
        vis.add(node);
        // list.add(node);
        for(int i:map.get(node))
        {
            if(!vis.contains(i))
            {
                dfs(map,vis,i);
            }
        }


    }
    static void topoSort(int start,HashMap<Integer,HashSet<Integer>> graph,HashSet<Integer> visited,Stack<Integer> stack)
    {
        visited.add(start);
        // inStack.add(start);
        for(int i:graph.get(start))
        {

            if(!visited.contains(i))
            {
                topoSort(i,graph,visited,stack);
            }
        }
        stack.push(start);
    }
    public int hammingDistance(int x, int y) {
        int count=0;
        for(int i=0;i<32;i++)
        {
            if((x&(1L<<i)) == (y&(1L<<i)))
            {
                count++;
            }
        }
        return count;
    }
    public String minInteger(String num, int k) {
        char[] arr1=num.toCharArray();
        int n=arr1.length;
        int[] arr=new int[n];
        for(int i=0;i<n;i++)
        {
            arr[i]=Character.getNumericValue(arr1[i]);
        }
        for(int i=0;i<arr.length && k>0;i++)
        {
            int ind=-1;
            int min=Integer.MAX_VALUE;
            for(int j=i;j<Math.min(i+k+1,n);j++)
            {
                if(arr[j]<min)
                {
                    min=arr[j];
                    ind=j;
                }
            }
            if(ind==i)
            {
                continue;
            }
            k-=ind-i;
            for(int j=ind;j>i;j--)
            {
                int temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
            }


        }
        StringBuilder res=new StringBuilder();
        for(int i:arr)
        {
            res.append(i);
        }
        return res.toString();
    }
    public static void main(String[] args) {
        StringBuilder ans = new StringBuilder();
//        int t = ri();
        int t=1;
//        sieve();
        while (t-- > 0)
        {
            int n=ri();
            int k=ri();
            long[] arr=ral(n);
            List<Long> pos=new ArrayList<>();
            List<Long> neg=new ArrayList<>();
            int z=0;
            for(long i:arr)
            {
                if(i<0)
                {
                    neg.add(i);
                }
                else if(i>=0)
                {
                    pos.add(i);
                }
            }
            pos.sort(new Comparator<Long>() {
                @Override
                public int compare(Long o1, Long o2) {
                    return o2.compareTo(o1);

                }
            });
            Collections.sort(neg);

            int i=0,j=0;
            long prod=1L;
            int count=0;
            while(count<k && i<pos.size() && j<neg.size())
            {

                if(count==k-1)
                {
                    if(i>=pos.size())
                    {
                        prod*=neg.get(neg.size()-1);
                        prod%=1000000007;
                        if(prod<0)
                        {
                            prod=1000000007+prod;
                        }
                    }
                    else
                    {
                        prod*=pos.get(i);
                        prod%=1000000007;
                        if(prod<0)
                        {
                            prod=1000000007+prod;
                        }
                    }
                    count++;
                }
                else
                {
                    long prod1=1L;
                    int f1=0;
                    if(i<=pos.size()-2)
                    {
                        f1=1;
                        prod1=pos.get(i)*pos.get(i+1);
                        i+=2;
                        prod1%=1000000007;
                        if(prod1<0)
                        {
                            prod1=1000000007+prod1;
                        }
                    }

                    int f2=0;

                    long prod2=1L;
                    if(j<=neg.size()-2)
                    {
                        f2=1;
                        prod2=neg.get(j)*neg.get(j+1);
                        j+=2;
                        prod2%=1000000007;
                        if(prod2<0)
                        {
                            prod2=1000000007+prod2;
                        }
                    }
                    if(f1==0)
                    {
                        prod*=prod2;prod%=1000000007;
                        if(prod<0)
                        {
                            prod=1000000007+prod;
                        }
                    }
                    else if(f2==0)
                    {
                        prod*=prod1;prod%=1000000007;
                        if(prod<0)
                        {
                            prod=1000000007+prod;
                        }
                    }
                    else {
                        if(prod1>=prod2)
                        {
                            j-=2;
                            prod*=prod1;prod%=1000000007;
                            if(prod<0)
                            {
                                prod=1000000007+prod;
                            }
                        }
                        else
                        {
                            i-=2;
                            prod*=prod2;prod%=1000000007;
                            if(prod<0)
                            {
                                prod=1000000007+prod;
                            }
                        }
                    }
                    count+=2;
                }
            }
            while(i<pos.size() && count<k)
            {
                prod*=pos.get(i);
                prod%=1000000007;
                if(prod<0)
                {
                    prod=1000000007+prod;
                }
                i++;
                count++;
            }
            if((k-count)%2==0)
            {
                while(j<neg.size() && count<k)
                {
                    prod*=neg.get(j);
                    prod%=1000000007;
                    if(prod<0)
                    {
                        prod=1000000007+prod;
                    }
                    j++;
                    count++;
                }
            }
            else
            {
                for(int x=neg.size()-1;x>=j && count<k;x--)
                {
                    prod*=neg.get(x);
                    prod%=1000000007;
                    if(prod<0)
                    {
                        prod=1000000007+prod;
                    }
//                    j++;
                    count++;
                }
            }
            ans.append(prod);
        }
        out.print(ans.toString());
        out.flush();

    }

}