SorahISA

F. A x B Problem

Jun 22nd, 2025
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.11 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using i64 = long long;
  5. #define int i64
  6. using u64 = unsigned long long;
  7. using i128 = __int128;
  8.  
  9. int safe_lg(int x) { return (x == 0 ? -1 : __lg(x)); }
  10.  
  11. int32_t main() {
  12.     cin.tie(0)->sync_with_stdio(0);
  13.    
  14.     int N; cin >> N;
  15.     int lgmx = 0;
  16.    
  17.     vector<u64> A(N);
  18.     for (auto &x : A) cin >> x, lgmx = max(lgmx, safe_lg(x) + 1);
  19.    
  20.     vector<u64> revA = A;
  21.     for (auto &x : revA) {
  22.         x = ((x >>  1) & 0x5555555555555555) | ((x & 0x5555555555555555) <<  1);
  23.         x = ((x >>  2) & 0x3333333333333333) | ((x & 0x3333333333333333) <<  2);
  24.         x = ((x >>  4) & 0x0F0F0F0F0F0F0F0F) | ((x & 0x0F0F0F0F0F0F0F0F) <<  4);
  25.         x = ((x >>  8) & 0x00FF00FF00FF00FF) | ((x & 0x00FF00FF00FF00FF) <<  8);
  26.         x = ((x >> 16) & 0x0000FFFF0000FFFF) | ((x & 0x0000FFFF0000FFFF) << 16);
  27.         x = ((x >> 32) & 0x00000000FFFFFFFF) | ((x & 0x00000000FFFFFFFF) << 32);
  28.     }
  29.    
  30.     auto fwt_and = [&](auto &a, int n, int op) {
  31.         for (int L = 2; L <= n; L <<= 1) {
  32.             for (int i = 0; i < n; i += L) for (int j = 0; j < L/2; ++j) {
  33.                 a[i+j] = (a[i+j] + a[i+j+L/2] * op);
  34.             }
  35.         }
  36.     };
  37.    
  38.     u64 U = (u64(1) << lgmx) - 1;
  39.     vector<i64> X(U + 1, 0);
  40.     vector<i128> Y(U + 1, 0);
  41.     for (auto x : A) ++X[x];
  42.    
  43.     for (int b = 0; b <= 2*lgmx-2; ++b) {
  44.         u64 u = (u64(1) << min(b+1, lgmx)) - 1;
  45.         for (auto x : revA) Y[(x >> (63-b)) & u] += i128(1) << b;
  46.     }
  47.    
  48.     fwt_and(X, U+1, 1);
  49.     fwt_and(Y, U+1, 1);
  50.     for (u64 i = 0; i <= U; ++i) Y[i] *= X[i];
  51.     fwt_and(Y, U+1, -1);
  52.    
  53.     for (int b = 0; b <= 2*lgmx-2; ++b) {
  54.         u64 u = (u64(1) << min(b+1, lgmx)) - 1;
  55.         for (int i = 0; i < N; ++i) Y[A[i] & (revA[i] >> (63-b)) & u] -= i128(1) << b;
  56.     }
  57.    
  58.     i128 ans = 0;
  59.     for (u64 i = 0; i <= U; ++i) { if (popcount(i) & 1) ans += Y[i]; }
  60.     ans /= 2;
  61.    
  62.     string ans_str;
  63.     do ans_str += char(ans % 10 + '0'), ans /= 10; while (ans);
  64.     reverse(begin(ans_str), end(ans_str));
  65.     cout << ans_str << "\n";
  66.    
  67.     return 0;
  68. }
  69.  
Add Comment
Please, Sign In to add comment