Problem: 2061D - Kevin and Numbers
Language: java

Solution 1 (runtime: 796 ms):
import java.io.*;
import java.util.*;

public class Main {
    public static int INF = 0x3f3f3f3f, mod = 1000000007, mod9 = 998244353;
    public static void main(String args[]){
        try {
            PrintWriter o = new PrintWriter(System.out);
            boolean multiTest = true;
            // init
            if(multiTest) {
                int t = nextInt(), loop = 0;
                while (loop < t) {loop++;solve(o);}
            } else solve(o);
            o.close();
        } catch (Exception e) {e.printStackTrace();}
    }
    static void solve(PrintWriter o) {
        try {
            int n = nextInt(), m = nextInt(), k = n-m;
            int[] a = new int[n];
            int[] b = new int[m];
            Map<Integer, Integer> map = new HashMap<>();
            for(int i=0;i<n;i++) {
                a[i] = nextInt();
                map.put(a[i], map.getOrDefault(a[i], 0)+1);
            }
            PriorityQueue<Integer> pq = new PriorityQueue<>((x,y)->Integer.compare(y,x));
            for(int i=0;i<m;i++) {
                b[i] = nextInt();
                pq.offer(b[i]);
            }
            while(!pq.isEmpty()) {
                int x = pq.poll();
                if(map.get(x) != null) {
                    map.put(x, map.get(x)-1);
                    if(map.get(x) == 0) map.remove(x);
                }
                else if(k-- > 0) {
                    pq.offer(x/2);
                    pq.offer((x+1)/2);
                }
                else {
                    o.println("No");
                    return;
                }
            }
            if(k > 0) o.println("No");
            else o.println("Yes");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static int lower_bound(Integer[] a, long val){
        int l = 0, r = a.length;
        while(l < r){
            int mid = l + (r - l) / 2;
            if(a[mid] < val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int lower_bound(List<Integer> li, long val){
        int l = 0, r = li.size();
        while(l < r){
            int mid = l + (r - l) / 2;
            if(li.get(mid) < val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int upper_bound(long[] preSum, long val){
        int l = 0, r = preSum.length;
        while(l < r){
            int mid = l + (r - l) / 2;
            if(preSum[mid] <= val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int upper_bound(List<int[]> li, long val){
        int l = 0, r = li.size();
        while(l < r){
            int mid = l + (r - l) / 2;
            if(li.get(mid)[0] <= val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int upper_bound(List<Integer> li, int val){
        int l = 0, r = li.size();
        while(l < r){
            int mid = l + (r - l) / 2;
            if(li.get(mid) <= val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int upper_bound(int[] a, long val){
        int l = 0, r = a.length;
        while(l < r){
            int mid = l + (r - l) / 2;
            if(a[mid] <= val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int lower_bound(List<int[]> li, int val){
        int l = 0, r = li.size();
        while(l < r){
            int mid = l + (r - l) / 2;
            if(li.get(mid)[0] < val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int lower_bound(int[] a, int val){
        int l = 0, r = a.length;
        while(l < r){
            int mid = l + (r - l) / 2;
            if(a[mid] < val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static int lower_bound(long[][] a, long val){
        int l = 0, r = a.length;
        while(l < r){
            int mid = l + (r - l) / 2;
            if(a[mid][0] < val) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public static long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a%b);
    }
    public static long[] extgcd(long a, long b) {
        if(b == 0) return new long[]{1, 0};
        long[] it = extgcd(b, a%b);
        long x = it[1], y = it[0];
        y -= a/b*x;
        return new long[]{x, y};
    }
    public static long lcm(long a, long b){
        return a / gcd(a,b)*b;
    }
    public static long qpow(long a, long n){
        long ret = 1l;
        while(n > 0){
            if((n & 1) == 1) ret = ret * a;
            n >>= 1;
            a = a * a;
        }
        return ret;
    }
    public static long qpow(long a, long n, int md){
        a %= md;
        long ret = 1l;
        while(n > 0){
            if((n & 1) == 1) ret = ret * a % md;
            n >>= 1;
            a = a * a % md;
        }
        return ret;
    }
    public static class FenWick {
        int n;
        long[] a;
        long[] tree;
        public FenWick(int n){
            this.n = n;
            a = new long[n+1];
            tree = new long[n+1];
        }
        private void add(int x, long val){
            while(x <= n){
                tree[x] += val;
                x += x&-x;
            }
        }
        private void addMx(int x, long val) {
            a[x] += val;
            tree[x] = a[x];
            while(x <= n) {
                for(int i=1;i<(x&-x);i<<=1) tree[x] = Math.max(tree[x], tree[x-i]);
                x += x&-x;
            }
        }
        private void addMn(int x, long val) {
            a[x] += val;
            tree[x] = a[x];
            while(x <= n) {
                for(int i=1;i<(x&-x);i<<=1) tree[x] = Math.min(tree[x], tree[x-i]);
                x += x&-x;
            }
        }
        private long query(int x){
            long ret = 0l;
            while(x > 0){
                ret += tree[x];
                x -= x&-x;
            }
            return ret;
        }
        private long queryMx(int l, int r) {
            long res = 0l;
            while(l <= r) {
                if(r-(r&-r) >= l) {
                    res = Math.max(res, tree[r]);
                    r -= r&-r;
                }
                else {
                    res = Math.max(res, a[r]);
                    r--;
                }
            }
            return res;
        }
        private long queryMn(int l, int r) {
            long res = 1l<<55;
            while(l <= r) {
                if(r-(r&-r) >= l) {
                    res = Math.min(res, tree[r]);
                    r -= r&-r;
                }
                else {
                    res = Math.min(res, a[r]);
                    r--;
                }
            }
            return res;
        }
    }
    static class Pair {
        Integer p1, p2;
        public Pair(Integer p1, Integer p2) {
            this.p1 = p1;
            this.p2 = p2;
        }
        @Override
        public int hashCode() {
            int prime = 31, ret = 0;
            ret = ret*prime+p1.hashCode();
            ret = ret*prime+p2.hashCode();
            return ret;
        }
        @Override
        public boolean equals(Object o) {
            if(o instanceof Pair pair) {
                return p1.equals(pair.p1) && p2.equals(pair.p2);
            }
            return false;
        }
    }
    static class DSU {
        int[] parent;
        int[] size;
        public DSU(int n) {
            parent = new int[n];
            size = new int[n];
            for(int i=0;i<n;i++) {
                parent[i] = i;
                size[i] = 1;
            }
        }
        public int find(int x) {
            if(parent[x] != x) parent[x] = find(parent[x]);
            return parent[x];
        }
        public void union(int x, int y) {
            int root_x = find(x);
            int root_y = find(y);
            if(root_x == root_y) return;
            parent[root_x] = root_y;
            size[root_y] += size[root_x];
            size[root_x] = 0;
        }
    }
    private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static StringTokenizer tokenizer = new StringTokenizer("");
    private static String next() throws IOException{
        while(!tokenizer.hasMoreTokens()){tokenizer = new StringTokenizer(reader.readLine());}
        return tokenizer.nextToken();
    }
    public static int nextInt() throws IOException {return Integer.parseInt(next());}
    public static Long nextLong() throws IOException {return Long.parseLong(next());}
    public static double nextDouble() throws IOException {return Double.parseDouble(next());}
    public static char nextChar() throws IOException {return next().toCharArray()[0];}
    public static String nextString() throws IOException {return next();}
    public static String nextLine() throws IOException {return reader.readLine();}
}

Solution 2 (runtime: 718 ms):


import java.io.*;

import java.util.*;



public class bcf{









    //functions to reduce time

    public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));







    public static int max=Integer.MAX_VALUE, min=Integer.MIN_VALUE;

    public static long maxl=(long)1e9, minl=Long.MIN_VALUE;

    public static long mod=1000000007;

    public static void main(String[] swami) throws FileNotFoundException {



        try {

//            File file = new File("/home/swamikedari/Documents/IdeaProjects/cpContests/src/testcases.txt");

//

//            // Check if the file exists

//            if (file.exists() && !file.isDirectory()) {

//                br = new BufferedReader(new FileReader(file));

//            }

            int t=getint();

            while(t-->0){

                int n=getint(), m=getint();

                long[] a=getarrl(n);

                long[] b=getarrl(m);



                PriorityQueue<Long> qa=new PriorityQueue<>(Comparator.reverseOrder());

                PriorityQueue<Long> qb=new PriorityQueue<>(Comparator.reverseOrder());

                for(long v: a)qa.add(v);

                for(long v: b)qb.add(v);

                boolean notpossible=false;

                while(!qa.isEmpty() && !qb.isEmpty() && qb.size()<=qa.size()){

                    while(!qb.isEmpty() && !Objects.equals(qb.peek(), qa.peek()) && qb.size()<=qa.size()) {

                        long minb = qb.remove();

                        qb.add((long)Math.ceil((double)minb/2));

                        qb.add((long)Math.floor((double)minb/2));

                    }

                    if(!qb.isEmpty() && qb.size()<=qa.size()) { qb.remove();qa.remove();}

                    else { notpossible=true; break;}

                }

                //println(qa.toString());

                //println(qb.toString());

                if(!qa.isEmpty() || !qb.isEmpty() || notpossible)println("NO");

                else println("YES");

            }

        }

        catch(Exception e){

            System.out.println(e);

        }

    }





    public static char value(char a,char b){

        String set="SET";

        for(int i = 0; i<set.length(); i++){

            if(set.charAt(i)!=a && set.charAt(i)!=b)return set.charAt(i);

        }

        return '?';

    }



    public static boolean isgreat(int[][] a,int i,int j){

        int[] xi={-1,0,1,0};

        int[] yi={0,-1,0,1};

        boolean isbig=true;

        for(int ind=0;ind<4;ind++){

            if(isbd(i+xi[ind],j+yi[ind],a.length,a[0].length)){

                if(a[i][j]<=a[i+xi[ind]][j+yi[ind]]){

                    isbig=false;

                }

            }

        }

        return isbig;

    }



    public static int maxval(int[][] a,int i,int j){

        int[] xi={-1,0,1,0};

        int[] yi={0,-1,0,1};

        int val=0;

        for(int ind=0;ind<4;ind++){

            if(isbd(i+xi[ind],j+yi[ind],a.length,a[0].length)){

                val=Math.max(a[i+xi[ind]][j+yi[ind]],val);

            }

        }

        return val;

    }





    public static boolean isbd(int i,int j,int n,int m){

        if(i>=0 && i<n && j>=0 && j<m)return true;

        return false;

    }





    public static boolean getans(long[] a,int i,long x,long[] ans){

        ans[0]++;

        if(i<0){

            return false;

        }

        if(x<0){

            return false;

        }

        if(x==0){

            return true;

        }

        boolean take=false;

        if(a[i]<=x){

            take=getans(a,i,x-a[i],ans);

        }

        boolean nottake=getans(a,i-1,x,ans);

        return take|nottake;

    }



    public static int getans(char[] ch,int i,int j, int n,int[][] dp){

        if(i==n){

            return 0;

        }

        int ans=(int)1e9;

        if(dp[i][j]!=-1){

            return dp[i][j];

        }

        if(j==0){

            int val=0;

            for(int k=i;k<=n;k++){

                ans=Math.min(ans,getans(ch,k,1,n,dp)+val);

                if(k<n && ch[k]=='b'){

                    val++;

                }

            }



            return dp[i][j]=ans;

        }

        else if(j==1){

            int val=0;

            for(int k=i;k<=n;k++){

                ans=Math.min(ans,getans(ch,k,2,n,dp)+val);

                if(k<n && ch[k]=='a'){

                    val++;

                }

            }

            return dp[i][j]=ans;

        }

        else{

                ans=0;

                for(int k=i;k<n;k++){

                    if(ch[k]!='a'){

                        ans++;

                    }

                }

                //println(ans);

                return dp[i][j]=ans;



        }

    }



    public static void dfs(ArrayList<ArrayList<Integer>> ar,int i,boolean[] vis,ArrayList<Integer> val){



        vis[i]=true;

        val.add(Integer.valueOf(i));

        for(int k: ar.get(i)){

            if(!vis[k]){

                dfs(ar,k,vis,val);

            }

        }

    }







    public static void dfs(ArrayList<HashSet<Integer>> ar,int i,boolean[] v){

        //print(i+" ");

        v[i]=true;

        for(int k: ar.get(i)){

            if(!v[k]){

                dfs(ar,k,v);

            }

        }

    }





    static StringTokenizer st=new StringTokenizer("");

    static String next() {

        while (!st.hasMoreTokens())

            try {

                st=new StringTokenizer(br.readLine());

            } catch (IOException e) {

                e.printStackTrace();

            }

        return st.nextToken();

    }









    public static int[] getarr(int n){

        int[] a=new int[n];

        for(int i=0;i<n;i++){

            a[i]=getint();

        }

        return a;

    }



    public static long[] getarrl(int n){

        long[] a=new long[n];

        for(int i=0;i<n;i++){

            a[i]=getlong();

        }

        return a;

    }

    public  static int getint(){

        return Integer.parseInt(next());

    }



    public  static long getlong(){

        return Long.parseLong(next());

    }



    public static String getstr(){

        return next();

    }



    // print statements



    public static void println(int i){

        System.out.println(i);

    }

    public static void println(String k){

        System.out.println(k);

    }



    public static void println(long k){

        System.out.println(k);

    }

    public static void println(float k){

        System.out.println(k);

    }

    public static void println(char k){

        System.out.println(k);

    }

    public static void println(double k){System.out.println(k); }

    public static void println(){System.out.println();}

    public static void println(int[] a){

        System.out.println(Arrays.toString(a));

    }

    public static void println(long[] a){

        System.out.println(Arrays.toString(a));

    }

    public static void println(char[] a){

        System.out.println(Arrays.toString(a));

    }

    public static void println(float[] a){

        System.out.println(Arrays.toString(a));

    }

    public static void println(double[] a){

        System.out.println(Arrays.toString(a));

    }

    public static void print(int[] A) {

        for(int i : A) {

            System.out.print(i+" ");

        }

        System.out.println();

    }

    public static void print(long[] A) {

        for(long i : A) {

            System.out.print(i+" ");

        }

        System.out.println();

    }



    public static void print(int i){

        System.out.print(i);

    }

    public static void print(String k){

        System.out.print(k);

    }

    public static void print(double k){System.out.print(k); }

    public static void print(long k){

        System.out.print(k);

    }

    public static void print(float k){

        System.out.print(k);

    }

    public static void print(char k){

        System.out.print(k);

    }





    // mod by the number

    static long mod(long x) {

        return ((x%mod + mod)%mod);

    }



    // gcd

    public static long gcd(long i,long j){

        if(i==0){

            return j;

        }

        return gcd(j%i,i);

    }



    // lcm

    public static long lcm(long i,long j){

        return i*j/gcd(i,j);

    }





    public static int gcd(int i,int j){

        if(i==0){

            return j;

        }

        return gcd(j%i,i);

    }



    // lcm

    public static int lcm(int i,int j){

        return i*j/gcd(i,j);

    }



    // quick sort



    public static void quicksort(int[] a,int l,int h){

        if(l<h){

            int pivot=partition(a,l,h);

            quicksort(a,l,pivot-1);

            quicksort(a,pivot+1,h);

        }

    }



    public static int partition(int[] a,int l,int h){

        int i=l-1;

        int piv=a[h];

        for(int j=l;j<h;j++){

            if(a[j]<piv){

                i++;

                swap(a,i,j);

            }

        }

        swap(a,i+1,h);

        return i+1;

    }



    public static void quicksortrev(int[] a,int l,int h){

        if(l<h){

            int pivot=partitionrev(a,l,h);

            quicksortrev(a,l,pivot-1);

            quicksortrev(a,pivot+1,h);

        }

    }



    public static int partitionrev(int[] a,int l,int h){

        int i=l-1;

        int piv=a[h];

        for(int j=l;j<h;j++){

            if(a[j]>piv){

                i++;

                swap(a,i,j);

            }

        }

        swap(a,i+1,h);

        return i+1;

    }



    public static void swap(int[] a,int i,int j){

        int temp=a[i];

        a[i]=a[j];

        a[j]=temp;



    }







    // binarysearch for the input and between the input



    public static int bs(int[] a,int i,int j,int k,int n){

        if(i<=j){

            int mid=mid(i,j);

            if(mid+1<n && a[mid]<=k && a[mid+1]>k){

                return mid;

            }

            else if(a[mid]<=k && mid==n-1){

                return mid;

            }

            else if(a[mid]>k && mid==0){

                return mid;

            }

            else if(a[mid]<k){

                return  bs(a,mid+1,j,k,n);

            }

            else{

                return bs(a,i,mid-1,k,n);

            }

        }

        return -1;

    }



    public static int mid(int i,int j){

        return (i+j)/2;

    }



    public static int bs(long[] a,int i,int j,long  k,int n){

        if(i<=j){

            int mid=mid(i,j);

            if(mid+1<n && a[mid]<=k && a[mid+1]>k){

                return mid;

            }

            else if(a[mid]<=k && mid==n-1){

                return mid;

            }

            else if(a[mid]<k){

                return  bs(a,mid+1,j,k,n);

            }

            else{

                return bs(a,i,mid-1,k,n);

            }

        }

        return -1;

    }



    public static long mid(long i,long j){

        return (i+j)/2;

    }



    // converting the int value to the char value and vice versa

    public static int toint(char a){

        return (int)a-48;

    }



    public static int tochar(int a){

        return (char)(a+48);

    }



    // converting the small alphabet characters to index and vice-versa

    public static int chartoint(char a){

        return (int)a-97;

    }



    public static char inttochar(int a){

        return (char)(a+97);

    }





    // important dp problems memoization solutions



    public static int lcs(String a,String b,int i,int j,int[][] dp,boolean[][] vis){

        if(i<0 || j<0){

            return 0;

        }

        if(vis[i][j]){

            return dp[i][j];

        }

        vis[i][j]=true;

        if(a.charAt(i)==b.charAt(j)){

            return dp[i][j]=lcs(a,b,i-1,j-1,dp,vis)+1;

        }

        else{

            return dp[i][j]=lcs(a,b,i-1,j,dp,vis);

        }

    }



    // power functions



    public static long pow(long a,long b){

        long ans=1;

        while(b!=0){

            if(b%2==1){

                ans=(ans*a)%1000000007;

            }

            a=a*a;

            a=a%1000000007;

            b/=2;

        }

        return ans;

    }





    // min and max functions



    public static int max(int a, int b){

        return Math.max(a, b);

    }



    public static int min(int a, int b){

        return Math.min(a, b);

    }





    static int max(int[] A) {

        int max=Integer.MIN_VALUE;

        for (int j : A) {

            max = Math.max(max, j);

        }

        return max;

    }

    static int min(int[] A) {

        int min=Integer.MAX_VALUE;

        for (int j : A) {

            min = Math.min(min, j);

        }

        return min;

    }

    static long max(long[] A) {

        long max=Long.MIN_VALUE;

        for (long l : A) {

            max = Math.max(max, l);

        }

        return max;

    }

    static long min(long[] A) {

        long min=Long.MAX_VALUE;

        for (long l : A) {

            min = Math.min(min, l);

        }

        return min;

    }



    // prime numbers related functions

    public static ArrayList<Integer> sieveOfEratosthenes(int n)

    {

        ArrayList<Integer> primes = new ArrayList<>();

        boolean[] prime = new boolean[n+1];

        for(int i=0;i<=n;i++)

            prime[i] = true;



        for(int p = 2; p*p <=n; p++)

        {



            if(prime[p])

            {



                for(int i = p*p; i <= n; i += p)

                    prime[i] = false;

            }

        }





        for(int i = 2; i <= n; i++)

        {

            if(prime[i])

                primes.add(Integer.valueOf(i));

        }

        return primes;

    }





    // prefix sum arrays and suffix sum array



    public static long [] prefix(long [] A) {

        long[] p=new long[A.length];

        p[0]=A[0];

        for(int i=1;i<A.length;i++)

            p[i]=p[i-1]+A[i];

        return p;

    }

    public static long [] prefix(int [] A) {

        long[] p=new long[A.length];

        p[0]=A[0];

        for(int i=1;i<A.length;i++)

            p[i]=p[i-1]+A[i];

        return p;

    }

    public static long [] suffix(long [] A) {

        long[] p=new long[A.length];

        p[A.length-1]=A[A.length-1];

        for(int i=A.length-2;i>=0;i--)

            p[i]=p[i+1]+A[i];

        return p;

    }

    public static long [] suffix(int [] A) {

        long[] p=new long[A.length];

        p[A.length-1]=A[A.length-1];

        for(int i=A.length-2;i>=0;i--)

            p[i]=p[i+1]+A[i];

        return p;

    }





    // hash map direct storage using the arrays



    public static HashMap<Long,Long> hash(long [] A){

        HashMap<Long,Long> map=new HashMap<Long, Long>();

        for(long i : A) {

            if(map.containsKey(i)) {

                map.put(i, map.get(i)+(long)1);

            }

            else {

                map.put(i, (long)1);

            }

        }

        return map;

    }



    public static HashMap<Integer,Long> hash(int[] A){

        HashMap<Integer,Long> map=new HashMap<Integer, Long>();

        for(int i : A) {

            if(map.containsKey(i)) {

                map.put(i, map.get(i)+(long)1);

            }

            else {

                map.put(i, (long)1);

            }

        }

        return map;

    }





    public static HashMap<Character,Long> hash(char [] A){

        HashMap<Character,Long> map=new HashMap<Character,Long>();

        for(char i : A) {

            if(map.containsKey(i)) {

                map.put(i, map.get(i)+(long)1);

            }

            else {

                map.put(i, (long)1);

            }

        }

        return map;

    }



    // segment tree implementation

    public static int[] array=new int[100005];

    public static int[] segarray=new int[4*100005];



    public static void buildmax(int ind,int low,int high){

        int mid=mid(low,high);

        if(low==high){

            segarray[ind]=array[low];

        }

        buildmax(2*ind+1,low,mid);

        buildmax(2*ind+2,mid+1,high);

        segarray[ind]=max(array[2*ind+1],array[2*ind+2]);



    }



    public static int querymax(int ind,int low,int high,int l,int r){

        if(low>=l && high<=r){

            return segarray[ind];

        }

        if(high<l || low>r){

            return min;

        }

        int mid=mid(low,high);

        int left=querymax(2*ind+1,low,mid,l,r);

        int right=querymax(2*ind+2,mid+1,high,l,r);

        return max(left,right);

    }





    public static void buildsum(int ind,int low,int high){

        int mid=mid(low,high);

        if(low==high){

            segarray[ind]=array[low];

        }

        buildsum(2*ind+1,low,high);

        buildsum(2*ind+2,low,high);

        segarray[ind]=segarray[2*ind+1]+segarray[2*ind+2];

    }



    public static int querysum(int ind,int low,int high,int l,int r){

        if (low >= l && high <= r) {

            return segarray[ind];

        }

        if(high<l || low>r){

            return 0;

        }

        int mid=mid(low,high);

        int left=querysum(2*ind+1,low,mid,l,r);

        int right=querysum(2*ind+2,mid+1,high,l,r);

        return left+right;



    }



















}