Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- class BigInteger;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- typedef pair < BigInteger, BigInteger > bipair;
- class BigInteger {
- private:
- constexpr static size_t SIZE = 1 << 7;
- uint pool[SIZE];
- size_t getblockbar() const {
- size_t bar = 0;
- for (size_t i = 0; i < SIZE; ++i) {
- bar = (pool[i] ? i : bar);
- }
- return bar;
- }
- size_t getbitbar() const {
- size_t blbar = pool[getblockbar()];
- for (size_t i = 0; i < 33; ++i) {
- if (blbar == 0) {
- return 32 * getblockbar() + i;
- }
- blbar >>= 1;
- }
- return -1;
- }
- static ull cut(ull n, size_t k) {
- return n & ((1ULL << k) - 1);
- }
- void plus(size_t p, uint n) {
- pool[p] ^= n;
- }
- void minus(size_t p, ull n) {
- if (pool[p] < n) {
- pool[p] += (1ULL << 32) - n;
- minus(p + 1, 1);
- } else {
- pool[p] -= n;
- }
- }
- static ull prod(ull a, ull b) {
- ull res = 0;
- while (b) {
- if (b & 1) {
- res ^= a;
- }
- a <<= 1;
- b >>= 1;
- }
- return res;
- }
- public:
- BigInteger() {
- for (auto &i : pool) {
- i = 0;
- }
- }
- BigInteger(const string &s): BigInteger() {
- for (size_t i = 0; i < s.size(); ++i) {
- if (s[i] == '1') {
- set_bit(i);
- }
- }
- }
- BigInteger(size_t n): BigInteger(string(n, '1')) {}
- operator string() const {
- string res;
- size_t bitbar = getbitbar();
- if (bitbar == 0) {
- return "0";
- }
- for (size_t i = 0; i < bitbar; ++i) {
- res += get_bit(i) + '0';
- }
- return res;
- }
- bool operator < (const BigInteger &n) const {
- for (int i = max(getblockbar(), n.getblockbar()); i >= 0; --i) {
- if (pool[i] != n.pool[i]) {
- return pool[i] < n.pool[i];
- }
- }
- return false;
- }
- bool operator == (uint n) const {
- return getblockbar() < 2 && pool[0] == n;
- }
- bool operator != (uint n) const {
- return !(*this == n);
- }
- operator bool() const {
- return *this != 0U;
- }
- void set_bit(size_t n, bool v = true) {
- if (v) {
- pool[n / 32] |= (1 << (n % 32));
- } else {
- pool[n / 32] &= ~(1 << (n % 32));
- }
- }
- bool get_bit(size_t n) const {
- return pool[n / 32] & (1 << (n % 32));
- }
- void shift_left (size_t n) {
- size_t a = n % 32,
- b = n / 32;
- size_t blbar = getblockbar();
- for (size_t i = blbar + 1; i; --i) {
- ull t = (1ULL * pool[i] << 32)
- | pool[i - 1];
- t <<= a;
- pool[i] = t >> 32;
- }
- pool[0] <<= a;
- if (b == 0){
- return;
- }
- for (size_t i = blbar + b + 1; i >= b; --i) {
- pool[i] = pool[i - b];
- pool[i - b] = 0;
- }
- }
- void shift_right (size_t n) {
- size_t a = n % 32,
- b = n / 32;
- size_t blbar = getblockbar();
- for (size_t i = 0; i <= blbar; ++i) {
- ull t = (1ULL * pool[i + 1] << 32)
- | pool[i];
- t >>= a;
- pool[i] = cut(t, 32);
- }
- if (b == 0) {
- return;
- }
- for (size_t i = 0; i <= blbar; ++i) {
- pool[i] = pool[i + b];
- pool[i + b] = 0;
- }
- }
- void cyclic_shift (size_t s) {
- shift_left(1);
- set_bit(0, get_bit(s));
- set_bit(s, false);
- }
- BigInteger operator + (const BigInteger &n) const {
- BigInteger res(*this);
- size_t bar = max(getblockbar(), n.getblockbar());
- for (size_t i = 0; i <= bar; ++i) {
- res.pool[i] ^= n.pool[i];
- }
- return res;
- }
- BigInteger& operator += (const BigInteger &n) {
- return *this = *this + n;
- }
- BigInteger operator & (const BigInteger &n) const {
- BigInteger res(*this);
- size_t bar = max(getblockbar(), n.getblockbar());
- for (size_t i = 0; i <= bar; ++i) {
- res.pool[i] &= n.pool[i];
- }
- return res;
- }
- BigInteger& operator &= (const BigInteger &n) {
- return *this = *this & n;
- }
- BigInteger mul(BigInteger, size_t) const;
- bool trace() const {
- bool res = 0;
- size_t bitbar = getbitbar();
- for (size_t i = 0; i <= bitbar; ++i) {
- res ^= get_bit(i);
- }
- return res;
- }
- static BigInteger pow(BigInteger a, BigInteger b, size_t s) {
- BigInteger res(s);
- while (b) {
- if (b.pool[0] & 1) {
- res = res.mul(a, s);
- }
- a = a.mul(a, s);
- b.shift_right(1);
- }
- return res;
- }
- void read(istream &is = cin) {
- string s;
- is >> s;
- reverse(s.begin(), s.end());
- *this = BigInteger(s);
- }
- void write(ostream &os = cout) const {
- string s = string(*this);
- reverse(s.begin(), s.end());
- os << s;
- }
- };
- istream& operator >> (istream &is, BigInteger &n) {
- n.read(is);
- return is;
- }
- ostream& operator << (ostream &os, const BigInteger &n) {
- n.write(os);
- return os;
- }
- class Matrix {
- private:
- static constexpr size_t SIZE = 650;
- size_t size;
- BigInteger pool[SIZE];
- static size_t bpow(size_t x, size_t n, size_t m) {
- if (n == 0) {
- return 1;
- }
- size_t r = bpow(x, n >> 1, m);
- r *= r;
- return (n & 1 ? r * x : r) % m;
- }
- static bool check(size_t x, size_t y, size_t m) {
- x = bpow(2, x, m);
- y = bpow(2, y, m);
- if (x < y) {
- swap(x, y);
- }
- return (x + y) % m == 1
- || (x - y) % m == 1
- || (x + y) % m == m - 1
- || (x - y) % m == m - 1;
- }
- public:
- Matrix (size_t n): size(n) {
- size_t m = 2 * size + 1;
- for (size_t i = 0; i < size; ++i) {
- for (size_t j = 0; j < size; ++j) {
- if (check(i, j, m)) {
- pool[i].set_bit(size - j - 1);
- }
- }
- }
- }
- BigInteger operator * (const BigInteger &n) const {
- BigInteger res;
- for (size_t i = 0; i < size; ++i) {
- if ((pool[i] & n).trace()) {
- res.set_bit(size - i - 1);
- }
- }
- return res;
- }
- };
- BigInteger BigInteger::mul(BigInteger n, size_t s) const {
- BigInteger res, t(*this);
- Matrix m(s);
- for (size_t i = 0; i < s; ++i) {
- res.set_bit(s - i - 1, ((m * t) & n).trace());
- t.cyclic_shift(s);
- n.cyclic_shift(s);
- }
- return res;
- }
- int main(){
- // freopen("/home/ellenord/qt/kek/input.txt", "r", stdin);
- // freopen("/home/ellenord/qt/kek/output.txt", "w", stdout);
- BigInteger x, y, z;
- cin >> x >> y >> z;
- cout << x + y << "\n"
- << x.mul(y, 281) << "\n"
- << x.mul(x, 281) << "\n"
- << BigInteger::pow(x, BigInteger(281) + BigInteger(1), 281) << "\n"
- << BigInteger::pow(x, z, 281) << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement