This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
#define pb push_back
#define x first
#define y second
using namespace std;
typedef pair < int , int > pii;
const int N = 100005, Mod = 1e9 + 7;
mt19937 Rnd;
struct Node
{
int sz = 0, p = 0, val = 0, cz = 0;
pii dp1, dp2;
Node * l = NULL, * r = NULL;
inline void Init()
{
p = Rnd();
dp1 = pii(1, 1);
dp2 = pii(cz >> 1, (cz + 1) >> 1);
}
};
typedef Node* Pode;
/* Treap */
inline int Size(Pode T)
{
return (T ? T->sz : 0);
}
inline void Func(Pode A, Pode B, Pode R)
{
vector < int > a = {A->dp1.x, A->dp1.y, A->dp2.x, A->dp2.y};
vector < int > b = {B->dp1.x, B->dp1.y, B->dp2.x, B->dp2.y};
R->dp1.x = (1LL * a[0] * b[0] + 1LL * a[2] * b[1]) % Mod;
R->dp1.y = (1LL * a[1] * b[0] + 1LL * a[3] * b[1]) % Mod;
R->dp2.x = (1LL * a[0] * b[2] + 1LL * a[2] * b[3]) % Mod;
R->dp2.y = (1LL * a[1] * b[2] + 1LL * a[3] * b[3]) % Mod;
}
inline void Upd(Pode T)
{
if (!T)
return ;
T->sz = Size(T->l) + Size(T->r) + 1;
T->dp1 = pii(1, 1);
T->dp2 = pii(T->cz >> 1, (T->cz + 1) >> 1);
if (T->l)
Func(T->l, T, T);
if (T->r)
Func(T, T->r, T);
}
void Split(Pode T, Pode &L, Pode &R, int c)
{
if (!T)
{
L = R = NULL;
return ;
}
if (Size(T->l) + 1 <= c)
Split(T->r, T->r, R, c - Size(T->l) - 1), L = T;
else
Split(T->l, L, T->l, c), R = T;
if (T) Upd(T);
}
void Merge(Pode &T, Pode L, Pode R)
{
if (!L)
T = R;
else if (!R)
T = L;
else if (L->p > R->p)
Merge(L->r, L->r, R), T = L;
else
Merge(R->l, L, R->l), T = R;
if (T) Upd(T);
}
void Split_by_value(Pode T, Pode &L, Pode &R, int val)
{
if (!T)
{
L = R = NULL;
return ;
}
if (T->val <= val)
Split_by_value(T->r, T->r, R, val), L = T;
else
Split_by_value(T->l, L, T->l, val), R = T;
if (T) Upd(T);
}
/* End */
int n, A[N];
int MnEd, MxEd;
set < int > B;
inline void Add(int a)
{
MnEd = min(MnEd, a);
MxEd = max(MxEd, a);
if (a < 0)
return ;
if (a == 0)
{
Add(1);
return ;
}
if (B.count(a))
{
B.erase(a);
Add(a + 1);
Add(a - 2);
return ;
}
if (B.count(a - 1))
{
B.erase(a - 1);
Add(a + 1);
return ;
}
if (B.count(a + 1))
{
B.erase(a + 1);
Add(a + 2);
return ;
}
B.insert(a);
}
inline int Solve()
{
int a = 1, b = 0;
for (auto it = B.begin(); it != B.end(); it ++)
{
int cz = (*it) - 1;
if (it != B.begin())
{
it --;
cz -= *it;
it ++;
}
a = (a + b) % Mod;
b = (1LL * (cz >> 1) * a + 1LL * (cz & 1) * b) % Mod;
}
return ((a + b) % Mod);
}
int main()
{
Pode T = new Node;
Rnd.seed(time(0));
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &A[i]);
MnEd = INT_MAX;
MxEd = INT_MIN;
Add(A[i]);
if (i == 1)
{
T->cz = A[i] - 1;
T->val = A[i];
T->Init();
printf("%d\n", (A[i] + 1) >> 1);
continue;
}
MnEd -= 5; MxEd += 5;
Pode a = NULL, b = NULL, c = NULL, d = NULL;
Split_by_value(T, a, b, MnEd);
Split_by_value(b, b, c, MxEd);
// b is garbage...
Pode K = new Node;
K->p = -1;
int aaaa = 0;
for (auto it = B.lower_bound(MnEd); it != B.end() && (*it) <= MxEd; it ++)
{
int cz = (*it) - 1;
if (it != B.begin())
{
it --;
cz -= *it;
it ++;
}
if (K->p == -1)
{
K->cz = cz;
K->val = A[i];
aaaa = A[i];
K->Init();
}
else
{
Pode tobe = new Node;
tobe->val = A[i];
aaaa = A[i];
tobe->cz = cz;
tobe->Init();
Merge(K, K, tobe);
}
}
if (c)
{
Split(c, c, d, 1);
c->cz = c->val - 1 - aaaa;
Merge(c, c, d);
}
Merge(T, a, K);
Merge(T, T, c);
printf("%d\n", (T->dp1.x + T->dp2.x) % Mod);
}
return (0);
}
Compilation message (stderr)
fib.cpp: In function 'int main()':
fib.cpp:150:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &n);
~~~~~^~~~~~~~~~
fib.cpp:153:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &A[i]);
~~~~~^~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |