제출 #1350222

#제출 시각아이디문제언어결과실행 시간메모리
1350222biankFibonacci representations (CEOI18_fib)C++20
65 / 100
1363 ms327680 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, int y) {
    return mul({1, y / 2, 0, 1}, {x / 2 + 1, x % 2, x / 2, x % 2});
}
 
vi vals;
set<ii> intervals;
 
const int INF = 1e9 + 2000;
 
using event = tuple<int, int, int>;
 
vector<vector<event>> events;
int t;
 
void addRange(int l, int r) {
    assert((r - l) % 2 == 0);
    if (l <= r) {
        events[t].eb(l, r, 1);
        intervals.emplace(l, r);
    }
}
 
void erase(auto it) {
    events[t].eb(it->fst, it->snd, 0);
    intervals.erase(it);
}
 
void add(int x) {
    auto it = intervals.upper_bound(make_pair(x, INF));
    auto [l, r] = *(--it);
    if (l <= x && x <= r) {
        if (l % 2 == x % 2) {
            erase(it);
            addRange(l + 1, x - 1);
            add(r + 1);
            if (l > 2) add(l - 2);
            else if (l == 2) add(l - 1);
        } else {
            addRange(l, x - 1);
            x = it->snd + 1;
            erase(it);
            add(x);
        }
    } else {
        auto left = it, right = next(it);
        if (x == right->fst - 1) {
            x = right->snd + 1;
            erase(right);
            add(x);
            return;
        }
        if (left->snd + 1 == x) {
            addRange(left->fst, left->snd - 2);
            erase(left);
            add(x + 1);
            return;
        }
        ii curr{x, x};
        if (x == right->fst - 2) {
            curr.snd = right->snd;
            erase(right);
        }
        if (x == left->fst + 2) {
            curr.fst = left->fst;
            erase(left);
        }
        addRange(curr.fst, curr.snd);
    }
}
 
vector<mat> st;
int 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));
}
 
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];
    
    intervals.emplace(-INF, -INF);
    intervals.emplace(INF, INF);
    events.resize(n);
    forn(i, n) {
        add(a[i]);
        t++;
    }
    
    vector<ii> allIntervals;
    forn(t, n) for (auto &[l, r, action] : events[t]) {
        if (action == 1) allIntervals.eb(l, r);
    }
    sort(all(allIntervals));
    allIntervals.erase(unique(all(allIntervals)), end(allIntervals));
    set<int> active;
    SZ = 1;
    while (SZ < sz(allIntervals)) SZ *= 2;
    st.assign(2 * SZ, NEUTR);
    forn(t, n) {
        for (auto [x, y, action] : events[t]) {
            int i = int(lower_bound(all(allIntervals), make_pair(x, y)) - begin(allIntervals));
            auto it = active.lower_bound(i);
            if (action == 1) {
                if (it != end(active)) {
                    int j = *it;
                    int len_j = allIntervals[j].snd - allIntervals[j].fst;
                    upd(j, value(allIntervals[j].fst - allIntervals[i].snd - 1, len_j));
                }
                int len_i = allIntervals[i].snd - allIntervals[i].fst;
                if (it != begin(active)) {
                    int j = *prev(it);
                    upd(i, value(allIntervals[i].fst - allIntervals[j].snd - 1, len_i));
                } else {
                    upd(i, value(allIntervals[i].fst - 1, len_i));
                }
                active.insert(i);
            } else {
                upd(i, NEUTR);
                it = active.erase(it);
                if (it != end(active)) {
                    i = *it;
                    int len = allIntervals[i].snd - allIntervals[i].fst;
                    if (it != begin(active)) {
                        int j = *prev(it);
                        upd(i, value(allIntervals[i].fst - allIntervals[j].snd - 1, len));
                    } else {
                        upd(i, value(allIntervals[i].fst - 1, len));
                    }
                }
            }
        }
        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...