Beingamanforever

Subarray XOR less than K

Nov 12th, 2024
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.68 KB | None | 0 0
  1. /**
  2.  *    author:  compounding
  3.  *    created: 2024-11-13 01:43:23
  4.  **/
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());
  8. #define NeedForSpeed                  \
  9.     ios_base::sync_with_stdio(false); \
  10.     cin.tie(NULL);                    \
  11.     cout.tie(NULL);
  12. #define int long long
  13. #define all(x) (x).begin(), (x).end()
  14. typedef vector<int> vi;
  15. typedef vector<bool> vb;
  16. typedef vector<vi> vvi;
  17. typedef vector<pair<int, int>> vpi;
  18. #define f first
  19. #define s second
  20. #define yes cout << "YES" << endl
  21. #define no cout << "NO" << endl
  22. #define endl "\n"
  23. const int mod = 1000000007;
  24. int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
  25. struct trie
  26. {
  27.     int leftcnt, rightcnt; // count of left and right children which have 0, 1 in the bit
  28.     trie *left, *right;    // reference to left and right child
  29.     trie()
  30.     {
  31.         leftcnt = 0;
  32.         rightcnt = 0;
  33.         left = NULL;
  34.         right = NULL;
  35.     }
  36. };
  37. void insert(trie *root, int value)
  38. {
  39.     for (int i = 31; i >= 0; i--)
  40.     {
  41.         int biton = (value >> i) & 1; // get the ith bit
  42.         // if ON
  43.         if (biton)
  44.         {
  45.             root->rightcnt++;
  46.             if (root->right == NULL)
  47.             {
  48.                 // go to it's right child
  49.                 root->right = new trie();
  50.             }
  51.             root = root->right;
  52.         }
  53.         else
  54.         {
  55.             root->leftcnt++;
  56.             if (root->left == NULL)
  57.             {
  58.                 // go to it's left child
  59.                 root->left = new trie();
  60.             }
  61.             root = root->left;
  62.         }
  63.     }
  64. }
  65. int query(trie *root, int value, int k)
  66. {
  67.     int ans = 0;
  68.     if (root == NULL)
  69.     {
  70.         return ans;
  71.     }
  72.     for (int i = 31; i >= 0; i--)
  73.     {
  74.         int biton = (value >> i) & 1; // get the ith bit
  75.         int bitk = (k >> i) & 1;      // get the ith bit
  76.         // TODO: if ith bit of k is ON
  77.         if (bitk)
  78.         {
  79.             // TODO : if ith bit of value is ON
  80.             if (biton)
  81.             {
  82.                 // add the right cnt, as we have to make the XOR < k so we have to switch this bit off
  83.                 ans += root->rightcnt;
  84.                 if (root->left == NULL)
  85.                 {
  86.                     return ans;
  87.                 }
  88.                 root = root->left;
  89.             }
  90.             else
  91.             {
  92.                 ans += root->leftcnt;
  93.                 if (root->right == NULL)
  94.                 {
  95.                     return ans;
  96.                 }
  97.                 root = root->right;
  98.             }
  99.         }
  100.         // TODO: if ith bit of k is OFF
  101.         else
  102.         {
  103.             // if ith bit of value is ON
  104.             if (biton)
  105.             {
  106.                 if (root->right == NULL)
  107.                 {
  108.                     return ans;
  109.                 }
  110.                 root = root->right;
  111.             }
  112.             else
  113.             {
  114.                 if (root->left == NULL)
  115.                 {
  116.                     return ans;
  117.                 }
  118.                 root = root->left;
  119.             }
  120.         }
  121.     }
  122.     return ans;
  123. }
  124. void solve()
  125. {
  126.     int n, k;
  127.     cin >> n >> k;
  128.     // number of subarrays with XOR less than k
  129.     vi a(n);
  130.     int prexor = 0, cnt = 0;
  131.     trie *root = new trie();
  132.     insert(root, 0);
  133.     for (int i = 0; i < n; i++)
  134.     {
  135.         cin >> a[i];
  136.         prexor ^= a[i];
  137.         cnt += query(root, prexor, k);
  138.         insert(root, prexor);
  139.     }
  140.     cout << cnt << endl;
  141.     return;
  142. }
  143.  
  144. signed main()
  145. {
  146.     NeedForSpeed;
  147.     int t = 1;
  148.     cin >> t;
  149.     while (t--)
  150.     {
  151.         solve();
  152.     }
  153.     return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment