import java.util.*; /* * Problem: XOR Partition (NAIPC19) * Author: Alex Coleman * Complexity: O(m*(n+2^m)) * * We will handle the bits in decreasing order. We first handle the highest bit, then show * that the problem splits into multiple instances, so we can repeat the process with next bit. * * Rough idea is look at the m-1 bit within a single partition, and think about the number X which * created the partition. There are 3 possibilities: * * 1. All numbers in this partition have the bit on. * In this case, we can show X must have the bit off * (if having the bit on in Y is in the partition, and X has the bit on, then Y with the bit off should also be in the partition) * * 2. All numbers in this partition have the bit off. * In this case, we can show X must have the bit on (same logic as 1) * * 3. Some have it, and some don't. * In this case, all partitions must be equal for this bit, and thus could be either value (and thus must all be type 3). * We double the answer once in this case since either option is available. * (suppose different partitions had different values; if X has it off, then leaving it off should make X lose to anyone with it on [and vice versa]) * * Note now that we split into separate problems for everyone who chooses a different type (1 or 2). * * Special cases: * If any partition is empty it is impossible, since for every X in our set, ~X will make X largest. * If two partitions are 'equivalent' (meaning they pick the same type at every step), it is impossible, since the * same number should not be in two partitions */ public class xor_partition_arc { static final long MOD = (long)1e9+7; public static void main(String[] args) { Scanner in = new Scanner(System.in); int m = in.nextInt(); int n = in.nextInt(); int mx = 1 << m; int[] ps = new int[mx]; for (int i=0;i=0;b--) { boolean[] ambig = new boolean[mx]; int[][] cnts = new int[mx][2]; for(int p=0;p> b)&1; int anyHave = (ors[p] >> b)&1; if(allHave == 1 || anyHave == 0) { cnts[prefix[p]][allHave]++; } else { ambig[prefix[p]] = true; } prefix[p] |= (1-allHave)< 0; if (onOff || ambigDefined) return 0; if (ambig[i]) ans = (ans*2)%MOD; } } boolean[] taken = new boolean[mx]; for(int i=0;i