Submission #1350174

#TimeUsernameProblemLanguageResultExecution timeMemory
1350174biankFibonacci representations (CEOI18_fib)C++20
65 / 100
4094 ms132092 KiB
#include <bits/stdc++.h>
 
using namespace std;
 
#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)
 
using vi = vector<int>;
using ii = pair<int, int>;
using vii = vector<ii>;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vb = vector<bool>;
using pll = pair<ll, ll>;
using bint = __int128;

#define sz(x) int(x.size())
#define all(x) begin(x), end(x)

#define pb push_back
#define eb emplace_back

#define fst first
#define snd second

const int MOD = 1e9 + 7;
const int MAX_A = 1e9 + 50;

const int T = 2;

using mat = array<array<int, T>, T>;

const mat NEUTR = []() {
    mat a;
    forn(i, T) forn(j, T) a[i][j] = i == j;
    return a;
}();

mat mul(mat a, mat b) {
    mat c;
    forn(i, T) forn(j, T) c[i][j] = 0;
    forn(i, T) forn(k, T) forn(j, T) {
        c[i][j] = (c[i][j] + 1LL * a[i][k] * b[k][j]) % MOD;
    }
    return c;
}

mat value(int x) {
    return {x / 2 + 1, x % 2, x / 2, x % 2};
}

set<int> fib;
vi vals;
 
void fakeAdd(int x) {
    if (fib.count(x)) {
        fib.erase(x);
        fakeAdd(x + 1);
        if (x > 2) fakeAdd(x - 2);
        else if (x == 2) fakeAdd(x - 1);
        return;
    }
    if (fib.count(x - 1)) {
        fib.erase(x - 1);
        fakeAdd(x + 1);
        return;
    }
    if (fib.count(x + 1)) {
        fib.erase(x + 1);
        fakeAdd(x + 2);
        return;
    }
    fib.insert(x);
    vals.pb(x);
}

const int SZ = 1 << 17;

mat st[2 * SZ];

void upd(int p, mat v) {
    for (st[p += SZ] = v; p /= 2; ) {
        st[p] = mul(st[2 * p + 1], st[2 * p]);
    }
}

int pos(int x) {
    auto it = lower_bound(all(vals), x);
    assert(it != end(vals) && *it == x);
    return int(it - begin(vals));
}

void erase(int x) {
    auto it = fib.lower_bound(x);
    upd(pos(x), NEUTR), it = fib.erase(it);
    if (it != end(fib)) {
        upd(pos(*it), value(*it - *prev(it) - 1));
    }
}

void insert(int x) {
    auto it = fib.lower_bound(x);
    if (it != end(fib)) {
        upd(pos(*it), value(*it - x - 1));
    }
    upd(pos(x), value(x - *prev(it) - 1));
    fib.insert(x);
}

void add(int x) {
    if (fib.count(x)) {
        erase(x);
        add(x + 1);
        if (x > 2) add(x - 2);
        else if (x == 2) add(x - 1);
        return;
    }
    if (x > 1 && fib.count(x - 1)) {
        erase(x - 1);
        add(x + 1);
        return;
    }
    if (fib.count(x + 1)) {
        erase(x + 1);
        add(x + 2);
        return;
    }
    insert(x);
}

int main() {
    ios::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);
    
    int n;
    cin >> n;
    vi a(n);
    forn(i, n) cin >> a[i];
    
    forn(i, n) fakeAdd(a[i]);
    
    sort(all(vals));
    vals.erase(unique(all(vals)), end(vals));
    
    forn(i, 2 * SZ) st[i] = NEUTR;
    fib = {0};
    forn(i, n) {
        add(a[i]);
        cout << st[1][0][0] << "\n";
    }
    
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...