EntropyIncreaser

nim mul

Aug 21st, 2020
1,243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.73 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <ctime>
  6. #include <cctype>
  7.  
  8. #include <algorithm>
  9. #include <tuple>
  10. #include <random>
  11. #include <bitset>
  12. #include <queue>
  13. #include <functional>
  14. #include <set>
  15. #include <map>
  16. #include <vector>
  17. #include <chrono>
  18. #include <iostream>
  19. #include <limits>
  20. #include <numeric>
  21.  
  22. using namespace std;
  23.  
  24. typedef unsigned int nimber;
  25.  
  26. nimber nim_mul_rec(nimber x, nimber y, int m) {
  27.   if (!x || !y) return 0;
  28.   if (m == 0) return 1;
  29.   int n = 1 << (m - 1);
  30.   nimber a = x >> n, b = x & ((1u << n) - 1u),
  31.          c = y >> n, d = y & ((1u << n) - 1u);
  32.   nimber ac = nim_mul_rec(a, c, m - 1), bd = nim_mul_rec(b, d, m - 1);
  33.   return ((nim_mul_rec(a ^ b, c ^ d, m - 1) ^ bd) << n) + (nim_mul_rec(1u << (n - 1), ac, m - 1) ^ bd);
  34. }
  35.  
  36. namespace F_2_16 {
  37.  
  38. const nimber R = 258;
  39.  
  40. nimber power_table[1 << 16];
  41. int index_table[1 << 16];
  42.  
  43. void init() {
  44.   nimber cur = 1;
  45.   for (int i = 0; i < (1 << 16) - 1; ++i) {
  46.     power_table[i] = cur;
  47.     index_table[cur] = i;
  48.     cur = nim_mul_rec(cur, R, 4);
  49.   }
  50. }
  51.  
  52. nimber nim_mul16(nimber x, nimber y) {
  53.   if (!x || !y) return 0;
  54.   int u = index_table[x], v = index_table[y];
  55.   if ((u += v) >= (1 << 16) - 1) u -= (1 << 16) - 1;
  56.   return power_table[u];
  57. }
  58.  
  59. }
  60.  
  61. nimber nim_mul32(nimber x, nimber y) {
  62.   if (!x || !y) return 0;
  63.   nimber a = x >> 16, b = x & ((1u << 16) - 1u),
  64.          c = y >> 16, d = y & ((1u << 16) - 1u);
  65.   nimber ac = F_2_16::nim_mul16(a, c), bd = F_2_16::nim_mul16(b, d);
  66.   return ((F_2_16::nim_mul16(a ^ b, c ^ d) ^ bd) << 16) + (F_2_16::nim_mul16(1u << 15, ac) ^ bd);
  67. }
  68.  
  69. int main() {
  70.   ios::sync_with_stdio(false);
  71.   cin.tie(nullptr);
  72.  
  73.   F_2_16::init();
  74.  
  75.  
  76.  
  77.   return 0;
  78. }
  79.  
Advertisement
Add Comment
Please, Sign In to add comment