Advertisement
Guest User

ZAEBALSYA

a guest
Dec 11th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.06 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. class BigInteger;
  6.  
  7. typedef unsigned int uint;
  8. typedef unsigned long long ull;
  9. typedef pair < BigInteger, BigInteger > bipair;
  10.  
  11. class BigInteger {
  12.  
  13. private:
  14.  
  15.     constexpr static size_t SIZE = 1 << 7;
  16.  
  17.     uint pool[SIZE];
  18.     size_t getblockbar() const {
  19.         size_t bar = 0;
  20.         for (size_t i = 0; i < SIZE; ++i) {
  21.             bar = (pool[i] ? i : bar);
  22.         }
  23.         return bar;
  24.     }
  25.     size_t getbitbar() const {
  26.         size_t blbar = pool[getblockbar()];
  27.         for (size_t i = 0; i < 33; ++i) {
  28.             if (blbar == 0) {
  29.                 return 32 * getblockbar() + i;
  30.             }
  31.             blbar >>= 1;
  32.         }
  33.         return -1;
  34.     }
  35.  
  36.     static ull cut(ull n, size_t k) {
  37.         return n & ((1ULL << k) - 1);
  38.     }
  39.  
  40.     void plus(size_t p, uint n) {
  41.         pool[p] ^= n;
  42.     }
  43.     void minus(size_t p, ull n) {
  44.         if (pool[p] < n) {
  45.             pool[p] += (1ULL << 32) - n;
  46.             minus(p + 1, 1);
  47.         } else {
  48.             pool[p] -= n;
  49.         }
  50.     }
  51.  
  52.     static ull prod(ull a, ull b) {
  53.         ull res = 0;
  54.         while (b) {
  55.             if (b & 1) {
  56.                 res ^= a;
  57.             }
  58.             a <<= 1;
  59.             b >>= 1;
  60.         }
  61.         return res;
  62.     }
  63.  
  64. public:
  65.  
  66.     BigInteger() {
  67.         for (auto &i : pool) {
  68.             i = 0;
  69.         }
  70.     }
  71.     BigInteger(const string &s): BigInteger() {
  72.         for (size_t i = 0; i < s.size(); ++i) {
  73.             if (s[i] == '1') {
  74.                 set_bit(i);
  75.             }
  76.         }
  77.     }
  78.     BigInteger(size_t n): BigInteger(string(n, '1')) {}
  79.  
  80.     operator string() const {
  81.         string res;
  82.         size_t bitbar = getbitbar();
  83.         if (bitbar == 0) {
  84.             return "0";
  85.         }
  86.         for (size_t i = 0; i < bitbar; ++i) {
  87.             res += get_bit(i) + '0';
  88.         }
  89.         return res;
  90.     }
  91.  
  92.     bool operator < (const BigInteger &n) const {
  93.         for (int i = max(getblockbar(), n.getblockbar()); i >= 0; --i) {
  94.             if (pool[i] != n.pool[i]) {
  95.                 return pool[i] < n.pool[i];
  96.             }
  97.         }
  98.         return false;
  99.     }
  100.  
  101.     bool operator == (uint n) const {
  102.         return getblockbar() < 2 && pool[0] == n;
  103.     }
  104.     bool operator != (uint n) const {
  105.         return !(*this == n);
  106.     }
  107.  
  108.     operator bool() const {
  109.         return *this != 0U;
  110.     }
  111.  
  112.     void set_bit(size_t n, bool v = true) {
  113.         if (v) {
  114.             pool[n / 32] |= (1 << (n % 32));
  115.         } else {
  116.             pool[n / 32] &= ~(1 << (n % 32));
  117.         }
  118.     }
  119.     bool get_bit(size_t n) const {
  120.         return pool[n / 32] & (1 << (n % 32));
  121.     }
  122.  
  123.     void shift_left (size_t n) {
  124.         size_t a = n % 32,
  125.                b = n / 32;
  126.         size_t blbar = getblockbar();
  127.         for (size_t i = blbar + 1; i; --i) {
  128.             ull t = (1ULL * pool[i] << 32)
  129.                   | pool[i - 1];
  130.             t <<= a;
  131.             pool[i] = t >> 32;
  132.         }
  133.         pool[0] <<= a;
  134.         if (b == 0){
  135.             return;
  136.         }
  137.         for (size_t i = blbar + b + 1; i >= b; --i) {
  138.             pool[i] = pool[i - b];
  139.             pool[i - b] = 0;
  140.         }
  141.     }
  142.     void shift_right (size_t n) {
  143.         size_t a = n % 32,
  144.                b = n / 32;
  145.         size_t blbar = getblockbar();
  146.         for (size_t i = 0; i <= blbar; ++i) {
  147.             ull t = (1ULL * pool[i + 1] << 32)
  148.                   | pool[i];
  149.             t >>= a;
  150.             pool[i] = cut(t, 32);
  151.         }
  152.         if (b == 0) {
  153.             return;
  154.         }
  155.         for (size_t i = 0; i <= blbar; ++i) {
  156.             pool[i] = pool[i + b];
  157.             pool[i + b] = 0;
  158.         }
  159.     }
  160.  
  161.     void cyclic_shift (size_t s) {
  162.         shift_left(1);
  163.         set_bit(0, get_bit(s));
  164.         set_bit(s, false);
  165.     }
  166.  
  167.     BigInteger operator + (const BigInteger &n) const {
  168.         BigInteger res(*this);
  169.         size_t bar = max(getblockbar(), n.getblockbar());
  170.         for (size_t i = 0; i <= bar; ++i) {
  171.             res.pool[i] ^= n.pool[i];
  172.         }
  173.         return res;
  174.     }
  175.     BigInteger& operator += (const BigInteger &n) {
  176.         return *this = *this + n;
  177.     }
  178.  
  179.     BigInteger operator & (const BigInteger &n) const {
  180.         BigInteger res(*this);
  181.         size_t bar = max(getblockbar(), n.getblockbar());
  182.         for (size_t i = 0; i <= bar; ++i) {
  183.             res.pool[i] &= n.pool[i];
  184.         }
  185.         return res;
  186.     }
  187.     BigInteger& operator &= (const BigInteger &n) {
  188.         return *this = *this & n;
  189.     }
  190.  
  191.     BigInteger mul(BigInteger, size_t) const;
  192.  
  193.     bool trace() const {
  194.         bool res = 0;
  195.         size_t bitbar = getbitbar();
  196.         for (size_t i = 0; i <= bitbar; ++i) {
  197.             res ^= get_bit(i);
  198.         }
  199.         return res;
  200.     }
  201.  
  202.     static BigInteger pow(BigInteger a, BigInteger b, size_t s) {
  203.         BigInteger res(s);
  204.         while (b) {
  205.             if (b.pool[0] & 1) {
  206.                 res = res.mul(a, s);
  207.             }
  208.             a = a.mul(a, s);
  209.             b.shift_right(1);
  210.         }
  211.         return res;
  212.     }
  213.  
  214.     void read(istream &is = cin) {
  215.         string s;
  216.         is >> s;
  217.         reverse(s.begin(), s.end());
  218.         *this = BigInteger(s);
  219.     }
  220.     void write(ostream &os = cout) const {
  221.         string s = string(*this);
  222.         reverse(s.begin(), s.end());
  223.         os << s;
  224.     }
  225.  
  226. };
  227.  
  228. istream& operator >> (istream &is, BigInteger &n) {
  229.     n.read(is);
  230.     return is;
  231. }
  232. ostream& operator << (ostream &os, const BigInteger &n) {
  233.     n.write(os);
  234.     return os;
  235. }
  236.  
  237. class Matrix {
  238.  
  239. private:
  240.  
  241.     static constexpr size_t SIZE = 650;
  242.  
  243.     size_t size;
  244.     BigInteger pool[SIZE];
  245.  
  246.     static size_t bpow(size_t x, size_t n, size_t m) {
  247.         if (n == 0) {
  248.             return 1;
  249.         }
  250.         size_t r = bpow(x, n >> 1, m);
  251.         r *= r;
  252.         return (n & 1 ? r * x : r) % m;
  253.     }
  254.  
  255.     static bool check(size_t x, size_t y, size_t m) {
  256.         x = bpow(2, x, m);
  257.         y = bpow(2, y, m);
  258.         if (x < y) {
  259.             swap(x, y);
  260.         }
  261.         return (x + y) % m == 1
  262.             || (x - y) % m == 1
  263.             || (x + y) % m == m - 1
  264.             || (x - y) % m == m - 1;
  265.     }
  266.  
  267. public:
  268.  
  269.     Matrix (size_t n): size(n) {
  270.         size_t m = 2 * size + 1;
  271.         for (size_t i = 0; i < size; ++i) {
  272.             for (size_t j = 0; j < size; ++j) {
  273.                 if (check(i, j, m)) {
  274.                     pool[i].set_bit(size - j - 1);
  275.                 }
  276.             }
  277.         }
  278.     }
  279.  
  280.     BigInteger operator * (const BigInteger &n) const {
  281.         BigInteger res;
  282.         for (size_t i = 0; i < size; ++i) {
  283.             if ((pool[i] & n).trace()) {
  284.                 res.set_bit(size - i - 1);
  285.             }
  286.         }
  287.         return res;
  288.     }
  289.  
  290. };
  291.  
  292. BigInteger BigInteger::mul(BigInteger n, size_t s) const {
  293.     BigInteger res, t(*this);
  294.     Matrix m(s);
  295.     for (size_t i = 0; i < s; ++i) {
  296.         res.set_bit(s - i - 1, ((m * t) & n).trace());
  297.         t.cyclic_shift(s);
  298.         n.cyclic_shift(s);
  299.     }
  300.     return res;
  301. }
  302.  
  303. int main(){
  304.  
  305. //  freopen("/home/ellenord/qt/kek/input.txt", "r", stdin);
  306. //  freopen("/home/ellenord/qt/kek/output.txt", "w", stdout);
  307.  
  308.     BigInteger x, y, z;
  309.     cin >> x >> y >> z;
  310.  
  311.     cout << x + y << "\n"
  312.          << x.mul(y, 281) << "\n"
  313.          << x.mul(x, 281) << "\n"
  314.          << BigInteger::pow(x, BigInteger(281) + BigInteger(1), 281) << "\n"
  315.          << BigInteger::pow(x, z, 281) << "\n";
  316.  
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement