이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
const int MaxN = 1e6 + 5;
struct Query
{
int l, r, id;
bool operator < (const Query& other) const
{
return this->r < other.r;
}
};
int n, q;
long long d;
long long arr[MaxN];
Query query[MaxN];
void Inp()
{
cin >> n >> d;
for (int x = 1; x <= n; x++)
{
cin >> arr[x];
}
cin >> q;
for (int x = 1; x <= q; x++)
{
cin >> query[x].l >> query[x].r;
query[x].id = x;
}
sort(query + 1, query + q + 1);
}
int parents[MaxN];
int sz[MaxN];
int mx[MaxN];
int mi[MaxN];
int FindSet(int p)
{
if (parents[p] == p)
{
return p;
}
parents[p] = FindSet(parents[p]);
return parents[p];
}
void UnionSet(int a, int b)
{
a = FindSet(a);
b = FindSet(b);
if (a == b)
{
return;
}
if (sz[a] < sz[b])
{
swap(a, b);
}
parents[b] = a;
sz[a] += sz[b];
mx[a] = max(mx[a], mx[b]);
mi[a] = min(mi[a], mi[b]);
}
long long SegTree[4 * MaxN];
long long Lazy[4 * MaxN];
void Fix(int id, int l, int r)
{
if (Lazy[id] == 0)
{
return;
}
SegTree[id] += Lazy[id] * (r - l + 1);
if (l != r)
{
Lazy[id << 1] += Lazy[id];
Lazy[id << 1 | 1] += Lazy[id];
}
Lazy[id] = 0;
}
void Update(int id, int l, int r, int i, int j, long long v)
{
Fix(id, l, r);
if (j < l || r < i)
{
return;
}
if (i <= l && r <= j)
{
Lazy[id] += v;
Fix(id, l, r);
return;
}
int mid = (l + r) >> 1;
Update(id << 1, l, mid, i, j, v);
Update(id << 1 | 1, mid + 1, r, i, j, v);
SegTree[id] = SegTree[id << 1] + SegTree[id << 1 | 1];
}
long long Get(int id, int l, int r, int i, int j)
{
Fix(id, l, r);
if (j < l || r < i)
{
return 0;
}
if (i <= l && r <= j)
{
return SegTree[id];
}
int mid = (l + r) >> 1;
return Get(id << 1, l, mid, i, j) + Get(id << 1 | 1, mid + 1, r, i, j);
}
long long res[MaxN];
void Exc()
{
for (int x = 1; x <= n; x++)
{
parents[x] = x;
sz[x] = 1;
mi[x] = x;
mx[x] = x;
}
for (int x = 1; x <= q; x++)
{
res[x] = -1;
}
int y = 1;
bool avl = true;
for (int x = 1; x <= n; x++)
{
int p = x;
while (p > 1 && arr[p - 1] - Get(1, 1, n, p - 1, p - 1) * d > arr[p] - Get(1, 1, n, p, p) * d)
{
int t = FindSet(p - 1);
long long k = arr[p - 1] - Get(1, 1, n, p - 1, p - 1) * d - (arr[p] - Get(1, 1, n, p, p) * d);
k = (k + d - 1) / d;
if (k * d > arr[mi[t]] - Get(1, 1, n, mi[t], mi[t]) * d)
{
avl = false;
break;
}
Update(1, 1, n, mi[t], mx[t], k);
UnionSet(p - 1, p);
p = mi[FindSet(p)];
}
if (!avl)
{
break;
}
while (y <= q && query[y].r == x)
{
res[query[y].id] = Get(1, 1, n, query[y].l, query[y].r);
y++;
}
}
for (int x = 1; x <= q; x++)
{
cout << res[x] << "\n";
}
}
int main()
{
//freopen("A.INP", "r", stdin);
//freopen("A.OUT", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int test = 1;
//cin >> test;
for (int x = 1; x <= test; x++)
{
Inp();
Exc();
}
return 0;
}
# | 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... |