1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| class Solution { class Tire { Tire[] Next = new Tire[2]; int Cnt; }
int ret; Tire root = new Tire();
public int countPairs(int[] nums, int low, int high) { int n = nums.length; int[] lowBit = bit(low); int[] highBit = bit(high); for (int i = n - 1; i >= 0; i--) { int[] bits = bit(nums[i]); countPairs(lowBit, highBit, bits); add(bits); } return ret; }
private void countPairs(int[] lowBit, int[] highBit, int[] bits) { int[] qbs1 = new int[32]; int[] qbs2 = new int[32]; int i = 0; for (; i < 32; i++) { if (lowBit[i] == 1 && highBit[i] == 1) qbs1[i] = qbs2 [i] = bits[i] ^ 1; if (lowBit[i] == 0 && highBit[i] == 0) qbs1[i] = qbs2 [i] = bits[i]; if (lowBit[i] == 0 && highBit[i] == 1) { qbs1[i] = bits[i]; qbs2[i] = bits[i] ^ 1; int idx = i + 1; for (; idx < 32; idx++) { if (lowBit[idx] == 1) qbs1[idx] = bits[idx] ^ 1; if (lowBit[idx] == 0) { qbs1[idx] = bits[idx] ^ 1; ret += query(qbs1, idx); qbs1[idx] = bits[idx]; } } ret += query(qbs1, idx); idx = i + 1; for (; idx < 32; idx++) { if (highBit[idx] == 0) qbs2[idx] = bits[idx]; if (highBit[idx] == 1) { qbs2[idx] = bits[idx]; ret += query(qbs2, idx); qbs2[idx] = bits[idx] ^ 1; } } ret += query(qbs2, idx); return; } } ret += query(qbs1, i); }
private int query(int[] bits, int cnt) { Tire cur = root; for (int i = 0; i <= cnt && i < 32; i++) { if (cur.Next[bits[i]] == null) return 0; cur = cur.Next[bits[i]]; } return cur.Cnt; }
private void add(int[] bits) { Tire cur = root; for (int i = 0; i < 32; i++) { if (cur.Next[bits[i]] == null) cur.Next[bits[i]] = new Tire(); cur.Next[bits[i]].Cnt++; cur = cur.Next[bits[i]]; } }
private int[] bit(int n) { int[] ret = new int[32]; int i = 31; for (; i >= 0; i--) { ret[i] = n & 1; n >>= 1; } return ret; }
}
|