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 <cstdio>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
const bool debug = false;
struct Item {
int a;
int b;
int i;
long long res;
bool operator< (const Item &O) const {
return b - a < O.b - O.a;
}
};
long long A[200006], B[200006];
void update(int l, int r, long long uA, long long uB) {
if (debug) printf("UPDATE: [%d,%d], %lld, %lld\n", l, r, uA, uB);
A[l] += uA;
B[l] += uB;
A[r + 1] -= uA;
B[r + 1] -= uB;
}
int n, m;
vector<Item> v;
// stick, x, [l, r]
void sum_left(int s, int x, int l, int r) {
if (debug) puts("SUM_LEFT");
if (x <= s) update(l, r, s - x, 0);
else update(l, r, x - s, -1);
}
void sum_right(int s, int x, int l, int r) {
if (debug) puts("SUM_RIGHT");
if (x >= s) update(l, r, x - s, 0);
else update(l, r, s - x, -1);
}
int main() {
scanf("%d%d", &n, &m);
v.resize(n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &v[i].a, &v[i].b);
v[i].i = i;
v[i].res = 0;
}
sort(v.begin(), v.end());
vector<pair<int, pair<int, bool>>> st; // pos, idx, stick to left?
st.push_back({ 0, { n - 1, true } });
for (int i = 0; i < m; i++) {
int x;
scanf("%d", &x);
int a = v[0].a, b = v[0].b;
if (st.back().second.second) {
a = st.back().first;
b = a + (v[0].b - v[0].a);
} else {
b = st.back().first;
a = b - (v[0].b - v[0].a);
}
if (a <= x && x <= b) continue;
int l = 0, r = n - 1;
while (l < r) {
int m = (l + r + 1) / 2;
int a, b;
{
int L = 0, R = (int)st.size() - 1;
while (L < R) {
int M = (L + R + 1) / 2;
if (st[M].second.first >= m) L = M;
else R = M - 1;
}
if (st[L].second.second) {
a = st[L].first;
b = a + (v[m].b - v[m].a);
} else {
b = st[L].first;
a = b - (v[m].b - v[m].a);
}
}
if (a <= x && x <= b) r = m - 1;
else l = m;
}
if (debug) printf("! SIZE=%d\n", (int)st.size());
int k = (int)st.size() - 1, lt = 0;
while (k >= 0 && st[k].second.first <= l) {
if (st[k].second.second) sum_left(st[k].first, x, lt, st[k].second.first);
else sum_right(st[k].first, x, lt, st[k].second.first);
lt = st[k].second.first + 1;
k--;
st.pop_back();
}
if (k >= 0) {
if (st[k].second.second) sum_left(st[k].first, x, lt, l);
else sum_right(st[k].first, x, lt, l);
}
if (x < a) st.push_back({ x, { l, true } });
else st.push_back({ x, { l, false } });
if (debug) {
printf("lt=%d, l=%d\n", lt, l);
puts("st:");
for (auto &i: st) printf("%d / %d / %d\n", i.first, i.second.first, i.second.second ? 1 : 0);
}
}
for (int i = 1; i < n; i++) A[i] += A[i - 1], B[i] += B[i - 1];
for (int i = 0; i < n; i++) v[i].res = A[i] + B[i] * (v[i].b - v[i].a);
sort(v.begin(), v.end(), [](const Item &a, const Item &b) {
return a.i < b.i;
});
for (int i = 0; i < n; i++) printf("%lld ", v[i].res);
}
Compilation message (stderr)
walls.cpp: In function 'int main()':
walls.cpp:47:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
47 | scanf("%d%d", &n, &m);
| ~~~~~^~~~~~~~~~~~~~~~
walls.cpp:50:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
50 | scanf("%d%d", &v[i].a, &v[i].b);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
walls.cpp:59:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
59 | scanf("%d", &x);
| ~~~~~^~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |