#include <bits/stdc++.h>
using namespace std;
// Zauwazmy, ze INF musi byc wiekszy od MAX_WARTOSC + log(n)
const int INF = 2e9 + 5;
const int MOD = 1e9 + 7;
struct Przedzial
{
int L, R;
bool operator < (const Przedzial& inny) const
{
if(L != inny.L)
{
return L < inny.L;
}
else
{
return R < inny.R;
}
}
bool operator == (const Przedzial& inny) const
{
return (L == inny.L && R == inny.R);
}
};
struct Macierz
{
// macierz[x][y] = macierz[najbardziej na prawo bit, ktorego nie musimy zmieniac][najbardziej na lewo bit, ktorego nie musimy zmieniac]
int macierz[2][2];
Macierz()
{
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
macierz[i][j] = 0;
}
}
}
int* operator [] (int indeks)
{
return macierz[indeks];
}
const int* operator [] (int indeks) const
{
return macierz[indeks];
}
Macierz operator * (const Macierz& inny) const
{
Macierz wynik;
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
for(int k = 0; k < 2; k++)
{
wynik[i][k] = (wynik[i][k] + 1LL * macierz[i][j] * inny.macierz[j][k]) % MOD;
}
}
}
return wynik;
}
};
struct Wierzcholek
{
bool czy_istnieje = false;
int najbardziej_na_lewo, najbardziej_na_prawo;
Macierz macierz;
void init(Przedzial przedzial)
{
najbardziej_na_lewo = przedzial.L, najbardziej_na_prawo = przedzial.R;
int rozmiar = (najbardziej_na_prawo - najbardziej_na_lewo) / 2 + 1;
macierz[0][0] = 1;
macierz[0][1] = 0;
macierz[1][0] = rozmiar - 1;
macierz[1][1] = 1;
}
void combine(const Wierzcholek& a, const Wierzcholek& b)
{
czy_istnieje = a.czy_istnieje || b.czy_istnieje;
if(!a.czy_istnieje)
{
*this = b;
return;
}
if(!b.czy_istnieje)
{
*this = a;
return;
}
najbardziej_na_lewo = a.najbardziej_na_lewo;
najbardziej_na_prawo = b.najbardziej_na_prawo;
const int odleglosc = b.najbardziej_na_lewo - a.najbardziej_na_prawo;
Macierz mid;
if(odleglosc % 2 == 0)
{
mid[0][0] = 1;
mid[1][0] = 1;
}
mid[0][1] = max(0, (odleglosc - 1) / 2);
mid[1][1] = max(0, (odleglosc - 1) / 2);
mid[1][1] = (mid[1][1] + 1) % MOD;
macierz = (b.macierz * mid) * a.macierz;
}
};
set <Przedzial> przedzialy;
vector <vector <Przedzial>> wydarzenia;
int timer;
void dodaj_jesli_niepuste(int L, int R)
{
if(L <= R)
{
wydarzenia[timer].push_back({L, R});
przedzialy.insert({L, R});
}
}
void usun(set <Przedzial>::iterator it)
{
wydarzenia[timer].push_back({it->L, it->R});
przedzialy.erase(it);
}
void dodaj_na_zewnatrz(const int liczba)
{
auto R = przedzialy.upper_bound({liczba, INF});
if(liczba + 1 == R->L)
{
// tuz przed przedzialem R
// caly przedzial kompresowujemy do R->R + 1
const int nowa_wartosc = R->R + 1;
usun(R);
dodaj_na_zewnatrz(nowa_wartosc);
return;
}
auto L = prev(R);
if(L->R + 1 == liczba)
{
// tuz za przedzialem L
// usuwamy ostatni element przedzialu L
dodaj_jesli_niepuste(L->L, L->R - 2);
usun(L);
dodaj_na_zewnatrz(liczba + 1);
return;
}
Przedzial nowy_przedzial = {liczba, liczba};
if(liczba + 2 == R->L)
{
nowy_przedzial.R = R->R;
usun(R);
}
if(L->R + 2 == liczba)
{
nowy_przedzial.L = L->L;
usun(L);
}
dodaj_jesli_niepuste(nowy_przedzial.L, nowy_przedzial.R);
}
void dodaj_mozliwe_do_wewnatrz(const int liczba)
{
auto it = przedzialy.upper_bound({liczba, INF});
it--;
if(!(it->L <= liczba && liczba <= it->R))
{
dodaj_na_zewnatrz(liczba);
return;
}
// Teraz juz wiemy, ze liczba jest w przedziale
if(it->L % 2 != liczba % 2)
{
// Mamy przypadek dodania do 0 w ciagu ...01010...
// ...001010101010100...
// + 1
// = ...001010100000010...
dodaj_jesli_niepuste(it->L, liczba - 1);
const int nowa_wartosc = it->R + 1;
usun(it);
dodaj_na_zewnatrz(nowa_wartosc);
}
else
{
// Mamy przypadek dodania do 1 w ciagu ...01010...
// ...001010101010100...
// + 1
// = ...100101011010100...
// = ...100101000000010...
const vector <int> nowe_wartosci = {it->L - 2, it->R + 1};
dodaj_jesli_niepuste(it->L + 1, liczba - 1);
usun(it);
for(auto a : nowe_wartosci)
{
if(a == -2)
{
// Fibonacci[-2] = 0
continue;
}
if(a == -1)
{
// Fibonacci[-1] = Fibonacci[0]
a = 0;
}
dodaj_na_zewnatrz(a);
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
wydarzenia.resize(n);
// Dla latwiejszej implementacji dodajemy dwa przedzialy
przedzialy.insert({-INF, -INF});
przedzialy.insert({INF, INF});
for(timer = 0; timer < n; timer++)
{
int liczba;
cin >> liczba;
liczba--;
dodaj_mozliwe_do_wewnatrz(liczba);
}
vector <Przedzial> wszystkie;
for(auto& wydarzenie : wydarzenia)
{
for(auto& x : wydarzenie)
{
wszystkie.push_back(x);
}
}
sort(wszystkie.begin(), wszystkie.end());
wszystkie.resize(unique(wszystkie.begin(), wszystkie.end()) - wszystkie.begin());
int potega = 1;
while(potega < (int) wszystkie.size())
{
potega *= 2;
}
vector <Wierzcholek> segtree(2 * potega);
for(int i = 0; i < (int) wszystkie.size(); i++)
{
segtree[potega + i].init(wszystkie[i]);
}
Wierzcholek start;
start.init({-1, -1});
start.czy_istnieje = true;
for(timer = 0; timer < n; timer++)
{
for(auto& x : wydarzenia[timer])
{
int pozycja = lower_bound(wszystkie.begin(),wszystkie.end(), x) - wszystkie.begin();
segtree[potega + pozycja].czy_istnieje = !segtree[potega + pozycja].czy_istnieje;
for(int i = (potega + pozycja) / 2; i >= 1; i /= 2)
{
segtree[i].combine(segtree[2 * i], segtree[2 * i + 1]);
}
}
Wierzcholek wynik;
wynik.combine(start, segtree[1]);
cout << wynik.macierz[1][1] << "\n";
}
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
204 KB |
Output is correct |
2 |
Correct |
0 ms |
204 KB |
Output is correct |
3 |
Correct |
0 ms |
204 KB |
Output is correct |
4 |
Correct |
0 ms |
204 KB |
Output is correct |
5 |
Correct |
0 ms |
204 KB |
Output is correct |
6 |
Correct |
0 ms |
204 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
204 KB |
Output is correct |
2 |
Correct |
0 ms |
204 KB |
Output is correct |
3 |
Correct |
0 ms |
204 KB |
Output is correct |
4 |
Correct |
0 ms |
204 KB |
Output is correct |
5 |
Correct |
0 ms |
204 KB |
Output is correct |
6 |
Correct |
0 ms |
204 KB |
Output is correct |
7 |
Correct |
0 ms |
204 KB |
Output is correct |
8 |
Correct |
1 ms |
204 KB |
Output is correct |
9 |
Correct |
1 ms |
332 KB |
Output is correct |
10 |
Correct |
1 ms |
204 KB |
Output is correct |
11 |
Correct |
1 ms |
332 KB |
Output is correct |
12 |
Correct |
1 ms |
332 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
204 KB |
Output is correct |
2 |
Correct |
1 ms |
204 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
204 KB |
Output is correct |
2 |
Correct |
0 ms |
204 KB |
Output is correct |
3 |
Correct |
0 ms |
204 KB |
Output is correct |
4 |
Correct |
0 ms |
204 KB |
Output is correct |
5 |
Correct |
0 ms |
204 KB |
Output is correct |
6 |
Correct |
0 ms |
204 KB |
Output is correct |
7 |
Correct |
0 ms |
204 KB |
Output is correct |
8 |
Correct |
1 ms |
204 KB |
Output is correct |
9 |
Correct |
1 ms |
332 KB |
Output is correct |
10 |
Correct |
1 ms |
204 KB |
Output is correct |
11 |
Correct |
1 ms |
332 KB |
Output is correct |
12 |
Correct |
1 ms |
332 KB |
Output is correct |
13 |
Correct |
0 ms |
204 KB |
Output is correct |
14 |
Correct |
1 ms |
204 KB |
Output is correct |
15 |
Correct |
0 ms |
204 KB |
Output is correct |
16 |
Correct |
1 ms |
332 KB |
Output is correct |
17 |
Correct |
1 ms |
204 KB |
Output is correct |
18 |
Correct |
1 ms |
332 KB |
Output is correct |
19 |
Correct |
1 ms |
204 KB |
Output is correct |
20 |
Correct |
1 ms |
332 KB |
Output is correct |
21 |
Correct |
1 ms |
332 KB |
Output is correct |
22 |
Correct |
1 ms |
332 KB |
Output is correct |
23 |
Correct |
1 ms |
332 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
204 KB |
Output is correct |
2 |
Correct |
211 ms |
19564 KB |
Output is correct |
3 |
Correct |
211 ms |
18740 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
204 KB |
Output is correct |
2 |
Correct |
0 ms |
204 KB |
Output is correct |
3 |
Correct |
0 ms |
204 KB |
Output is correct |
4 |
Correct |
0 ms |
204 KB |
Output is correct |
5 |
Correct |
0 ms |
204 KB |
Output is correct |
6 |
Correct |
0 ms |
204 KB |
Output is correct |
7 |
Correct |
0 ms |
204 KB |
Output is correct |
8 |
Correct |
1 ms |
204 KB |
Output is correct |
9 |
Correct |
1 ms |
332 KB |
Output is correct |
10 |
Correct |
1 ms |
204 KB |
Output is correct |
11 |
Correct |
1 ms |
332 KB |
Output is correct |
12 |
Correct |
1 ms |
332 KB |
Output is correct |
13 |
Correct |
0 ms |
204 KB |
Output is correct |
14 |
Correct |
1 ms |
204 KB |
Output is correct |
15 |
Correct |
0 ms |
204 KB |
Output is correct |
16 |
Correct |
1 ms |
332 KB |
Output is correct |
17 |
Correct |
1 ms |
204 KB |
Output is correct |
18 |
Correct |
1 ms |
332 KB |
Output is correct |
19 |
Correct |
1 ms |
204 KB |
Output is correct |
20 |
Correct |
1 ms |
332 KB |
Output is correct |
21 |
Correct |
1 ms |
332 KB |
Output is correct |
22 |
Correct |
1 ms |
332 KB |
Output is correct |
23 |
Correct |
1 ms |
332 KB |
Output is correct |
24 |
Correct |
1 ms |
204 KB |
Output is correct |
25 |
Correct |
211 ms |
19564 KB |
Output is correct |
26 |
Correct |
211 ms |
18740 KB |
Output is correct |
27 |
Correct |
51 ms |
5780 KB |
Output is correct |
28 |
Correct |
98 ms |
10000 KB |
Output is correct |
29 |
Correct |
59 ms |
5816 KB |
Output is correct |
30 |
Correct |
96 ms |
9856 KB |
Output is correct |
31 |
Correct |
143 ms |
15536 KB |
Output is correct |
32 |
Correct |
119 ms |
10740 KB |
Output is correct |
33 |
Correct |
174 ms |
15372 KB |
Output is correct |
34 |
Correct |
183 ms |
15532 KB |
Output is correct |
35 |
Correct |
216 ms |
15036 KB |
Output is correct |
36 |
Correct |
249 ms |
15196 KB |
Output is correct |
37 |
Correct |
211 ms |
9208 KB |
Output is correct |
38 |
Correct |
205 ms |
19544 KB |
Output is correct |
39 |
Correct |
81 ms |
8324 KB |
Output is correct |
40 |
Correct |
129 ms |
11316 KB |
Output is correct |
41 |
Correct |
323 ms |
12560 KB |
Output is correct |
42 |
Correct |
227 ms |
19516 KB |
Output is correct |
43 |
Correct |
153 ms |
11512 KB |
Output is correct |
44 |
Correct |
276 ms |
30568 KB |
Output is correct |
45 |
Correct |
342 ms |
31192 KB |
Output is correct |
46 |
Correct |
333 ms |
31400 KB |
Output is correct |
47 |
Correct |
287 ms |
21964 KB |
Output is correct |
48 |
Correct |
376 ms |
31528 KB |
Output is correct |
49 |
Correct |
432 ms |
31216 KB |
Output is correct |
50 |
Correct |
241 ms |
20788 KB |
Output is correct |