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;
int fi;
int se;
bool operator< (const Item &O) const {
return b - a < O.b - O.a;
}
};
pair<long long, long long> operator+ (const pair<long long, long long> &a, const pair<long long, long long> &b) {
return { a.first + b.first, a.second + b.second };
}
pair<long long, long long> lazy1[524288], lazy2[524288];
void propagate1(int i, int b, int e) {
if (b != e) {
lazy1[i * 2 + 1] = lazy1[i * 2 + 1] + lazy1[i];
lazy1[i * 2 + 2] = lazy1[i * 2 + 2] + lazy1[i];
lazy1[i] = { 0, 0 };
}
}
pair<long long, long long> query1(int i, int b, int e, int p) {
propagate1(i, b, e);
if (p < b || e < p) return { 0, 0 };
if (b == e) return lazy1[i];
int m = (b + e) / 2;
return query1(i * 2 + 1, b, m, p) + query1(i * 2 + 2, m + 1, e, p);
}
void substitute1(int i, int b, int e, int p, long long v) {
propagate1(i, b, e);
if (p < b || e < p) return;
if (b == e) {
lazy1[i] = { v, 0 };
return;
}
int m = (b + e) / 2;
substitute1(i * 2 + 1, b, m, p, v);
substitute1(i * 2 + 2, m + 1, e, p, v);
}
void update1(int i, int b, int e, int l, int r, long long v1, long long v2) {
propagate1(i, b, e);
if (r < l || r < b || e < l) return;
if (l <= b && e <= r) {
lazy1[i] = lazy1[i] + make_pair(v1, v2);
return;
}
int m = (b + e) / 2;
update1(i * 2 + 1, b, m, l, r, v1, v2);
update1(i * 2 + 2, m + 1, e, l, r, v1, v2);
}
void propagate2(int i, int b, int e) {
if (b != e) {
lazy2[i * 2 + 1] = lazy2[i * 2 + 1] + lazy2[i];
lazy2[i * 2 + 2] = lazy2[i * 2 + 2] + lazy2[i];
lazy2[i] = { 0, 0 };
}
}
pair<long long, long long> query2(int i, int b, int e, int p) {
propagate2(i, b, e);
if (p < b || e < p) return { 0, 0 };
if (b == e) return lazy2[i];
int m = (b + e) / 2;
return query2(i * 2 + 1, b, m, p) + query2(i * 2 + 2, m + 1, e, p);
}
void substitute2(int i, int b, int e, int p, long long v) {
propagate2(i, b, e);
if (p < b || e < p) return;
if (b == e) {
lazy2[i] = { v, 0 };
return;
}
int m = (b + e) / 2;
substitute2(i * 2 + 1, b, m, p, v);
substitute2(i * 2 + 2, m + 1, e, p, v);
}
void update2(int i, int b, int e, int l, int r, long long v1, long long v2) {
propagate2(i, b, e);
if (r < l || r < b || e < l) return;
if (l <= b && e <= r) {
lazy2[i] = lazy2[i] + make_pair(v1, v2);
return;
}
int m = (b + e) / 2;
update2(i * 2 + 1, b, m, l, r, v1, v2);
update2(i * 2 + 2, m + 1, e, l, r, v1, v2);
}
long long query1(int x, int l) {
pair<long long, long long> t = query1(0, 0, 262143, x);
return t.first + t.second * l;
}
long long query2(int x, int l) {
pair<long long, long long> t = query2(0, 0, 262143, x);
return t.first + t.second * l;
}
void update1(int p, long long v) {
substitute1(0, 0, 262143, p, v);
}
void update2(int p, long long v) {
substitute2(0, 0, 262143, p, v);
}
void update1(int l, int r, long long uA, long long uB) {
update1(0, 0, 262143, l, r, uA, uB);
}
void update2(int l, int r, long long uA, long long uB) {
update2(0, 0, 262143, l, r, uA, uB);
}
void update(int l, int r, long long uA, long long uB, int y) {
if (debug) printf("UPDATE: [%d,%d], %lld, %lld\n", l, r, uA, uB);
if (y) update2(l, r, uA, uB);
else update1(l, r, uA, uB);
}
int n, m, p[200006];
vector<Item> v, v1, v2;
long long res[200006];
// stick, x, [l, r]
void sum_left(int s, int x, int l, int r, int y) {
if (debug) puts("SUM_LEFT");
if (x <= s) update(l, r, s - x, 0, y);
else update(l, r, x - s, -1, y);
}
void sum_right(int s, int x, int l, int r, int y) {
if (debug) puts("SUM_RIGHT");
if (x >= s) update(l, r, x - s, 0, y);
else update(l, r, s - x, -1, y);
}
void process(vector<Item> &v, vector<pair<int, pair<int, bool>>> &st, int x, int y) {
if (debug) puts("PROCESS");
if (v.empty()) return;
int n = (int)v.size();
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) return;
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, y);
else sum_right(st[k].first, x, lt, st[k].second.first, y);
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, y);
else sum_right(st[k].first, x, lt, l, y);
}
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);
}
}
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].fi = v[i].se = (int)1e9;
}
for (int i = 0; i < m; i++) scanf("%d", p + i);
vector<pair<int, int>> queries1, queries2;
vector<pair<int, pair<bool, int>>> queries;
for (int i = 0; i < n; i++) {
// v[i].a 미만 중 첫번: v[i].fi
queries1.push_back({ v[i].a, i });
// v[i].b 초과 중 첫번: v[i].se
queries2.push_back({ v[i].b, i });
}
{
sort(queries1.rbegin(), queries1.rend());
int k = 0;
for (int i = 0; i < m; i++) {
while (k < (int)queries1.size() && p[i] < queries1[k].first) {
v[queries1[k].second].fi = i;
k++;
}
}
}
{
sort(queries2.begin(), queries2.end());
int k = 0;
for (int i = 0; i < m; i++) {
while (k < (int)queries2.size() && p[i] > queries2[k].first) {
v[queries2[k].second].se = i;
k++;
}
}
}
sort(v.begin(), v.end());
for (auto &i: v) {
if (i.fi < i.se) {
queries.push_back({ i.fi, { true, (int)v1.size() } });
v1.push_back(i);
}
if (i.fi > i.se) {
queries.push_back({ i.se, { false, (int)v2.size() } });
v2.push_back(i);
}
}
sort(queries.begin(), queries.end());
vector<pair<int, pair<int, bool>>> st1, st2; // pos, idx, stick to left?
st1.push_back({ (int)1e9, { n - 1, true } });
st2.push_back({ (int)-1e9, { n - 1, false } });
if (debug) printf("v1=%d / v2=%d\n", (int)v1.size(), (int)v2.size());
int k = 0;
for (int i = 0; i < m; i++) {
process(v1, st1, p[i], 0);
process(v2, st2, p[i], 1);
while (k < (int)queries.size() && queries[k].first <= i) {
if (queries[k].second.first) update1(queries[k].second.second, v1[queries[k].second.second].a - p[i]);
else update2(queries[k].second.second, p[i] - v2[queries[k].second.second].b);
k++;
}
}
for (int i = 0; i < (int)v1.size(); i++) res[v1[i].i] = query1(i, v1[i].b - v1[i].a);
for (int i = 0; i < (int)v2.size(); i++) res[v2[i].i] = query2(i, v2[i].b - v2[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++) {
if (debug) printf("\nFI=%d / SE=%d\n", v[i].fi, v[i].se);
if (v[i].fi == (int)1e9 && v[i].se == (int)1e9) puts("0");
else printf("%lld\n", res[i]);
}
}
Compilation message (stderr)
walls.cpp: In function 'int main()':
walls.cpp:214:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
214 | scanf("%d%d", &n, &m);
| ~~~~~^~~~~~~~~~~~~~~~
walls.cpp:217:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
217 | scanf("%d%d", &v[i].a, &v[i].b);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
walls.cpp:221:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
221 | for (int i = 0; i < m; i++) scanf("%d", p + 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... |