NKGIFTS - VOI08 Quà tết

Tác giả: ladpro98

Ngôn ngữ: C++

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, a, b) for(int i = (a); i <=(b); i++)
#define FORD(i, a, b) for(int i = (a); i > (b); i--)
#define REPD(i, a, b) for(int i = (a); i >=(b); i--)
#define TR(it, a) for(typeof((a).begin()) it = (a).begin(); it != (a).end(); ++it)
#define RESET(a, v) memset((a), (v), sizeof((a)))
#define SZ(a) (int((a).size()))
#define ALL(a) (a).begin(), (a).end()
#define PB push_back
#define MP make_pair
#define LL long long
#define LD long double
#define II pair<int, int>
#define X first
#define Y second
#define VI vector<int>
const int BASE = 10000;
const int LEN = 4;
using namespace std;

typedef VI big;

void fix(big &a) {
    a.PB(0);
    FOR(i, 0, SZ(a) - 1) {
        a[i + 1] += a[i] / BASE; a[i] %= BASE;
        if (a[i] < 0) {a[i] += BASE; a[i + 1]--;}
    }
    while (SZ(a) > 1 && a.back() == 0) a.pop_back();
}

void operator += (big &a, big &b) {
    a.resize(max(SZ(a), SZ(b)));
    FOR(i, 0, SZ(b)) a[i] += b[i];
    fix(a);
}

void operator -= (big &a, big &b)
    {FOR(i, 0, SZ(b)) a[i] -= b[i]; fix(a);}

big operator + (big a, big b) {a += b; return a;}
big operator - (big a, big b) {a -= b; return a;}

LL lim, p, q, u, v;
big POW[100];

big ans(int k, LL x, LL y, big pos) {
    if (k == 0) return pos;
    big h = POW[lim - k << 1];
    LL mid = 1ll << (k - 1);
    bool uu = x < mid, ll = y < mid;
    if (ll  &&  uu) return ans(k - 1, x, mid - 1 - y, h - pos + big(1, 1));
    if (!ll &&  uu) return ans(k - 1, x, y - mid, h + h + h + pos);
    if (ll  && !uu) return ans(k - 1, mid * 2 - x - 1, mid - 1 - y, h + pos);
                    return ans(k - 1, mid * 2 - x - 1, y - mid, h + h + h - pos + big(1, 1));
}

ostream& operator << (ostream& cout, const big &a) {
    printf("%d", a.back());
    REPD(i, SZ(a) - 2, 0) printf("%04d", a[i]);
    return cout;
}

int main() {
    POW[0] = big(1, 1);
    FOR(i, 1, 100) POW[i] = POW[i - 1] + POW[i - 1];
    cin >> lim >> p >> q >> u >> v;
    cout << ans(lim, p, q, big(1, 1)) << ' ' << ans(lim, u, v, big(1, 1));
    return 0;
}

Download