This commit is contained in:
subcrip 2024-06-01 16:17:15 +08:00
parent 3f48d4b954
commit d82e0e4b5c
Signed by: subcrip
SSH Key Fingerprint: SHA256:dFPFi68d8C87YkFkEBU4TkcrYRySWpekRR1hbnDWUCw
5 changed files with 249 additions and 214 deletions

Binary file not shown.

View File

@ -1,8 +1,8 @@
/**
* Author: subcrip
* Created: 2024-05-31 23:31:18
* Modified: 2024-06-01 00:53:27
* Elapsed: 82 minutes
* Created: 2024-06-01 13:45:49
* Modified: 2024-06-01 15:48:33
* Elapsed: 122 minutes
*/
#pragma GCC optimize("Ofast")
@ -485,7 +485,7 @@ template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container)
}
/////////////////////////////////////////////////////////
// #define SINGLE_TEST_CASE
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
@ -496,177 +496,121 @@ void dump_ignore() {}
void prep() {
}
template<typename Addable_Info_t, typename Tag_t, typename Sequence = std::vector<Addable_Info_t>> class segtree {
private:
using size_type = uint64_t;
using info_type = Addable_Info_t;
using tag_type = Tag_t;
size_type _max;
vector<info_type> d;
vector<tag_type> b;
void pull(size_type p) {
d[p] = d[p * 2] + d[p * 2 + 1];
}
void push(size_type p, size_type left_len, size_type right_len) {
d[p * 2].apply(b[p], left_len), d[p * 2 + 1].apply(b[p], right_len);
b[p * 2].apply(b[p]), b[p * 2 + 1].apply(b[p]);
b[p] = tag_type();
}
void set(size_type s, size_type t, size_type p, size_type x, const info_type& c) {
if (s == t) {
d[p] = c;
return;
}
size_type m = s + (t - s >> 1);
if (s != t) push(p, m - s + 1, t - m);
if (x <= m) set(s, m, p * 2, x, c);
else set(m + 1, t, p * 2 + 1, x, c);
pull(p);
}
void range_apply(size_type s, size_type t, size_type p, size_type l, size_type r, const tag_type& c) {
if (l <= s && t <= r) {
d[p].apply(c, t - s + 1);
b[p].apply(c);
return;
}
size_type m = s + (t - s >> 1);
push(p, m - s + 1, t - m);
if (l <= m) range_apply(s, m, p * 2, l, r, c);
if (r > m) range_apply(m + 1, t, p * 2 + 1, l, r, c);
pull(p);
}
info_type range_query(size_type s, size_type t, size_type p, size_type l, size_type r) {
if (l <= s && t <= r) {
return d[p];
}
size_type m = s + (t - s >> 1);
info_type res = {};
push(p, m - s + 1, t - m);
if (l <= m) res = res + range_query(s, m, p * 2, l, r);
if (r > m) res = res + range_query(m + 1, t, p * 2 + 1, l, r);
return res;
}
void build(const Sequence& a, size_type s, size_type t, size_type p) {
if (s == t) {
d[p] = a[s];
return;
}
int m = s + (t - s >> 1);
build(a, s, m, p * 2);
build(a, m + 1, t, p * 2 + 1);
pull(p);
}
public:
segtree(size_type __max) : d(4 * __max), b(4 * __max), _max(__max - 1) {}
segtree(const Sequence& a) : segtree(a.size()) {
build(a, {}, _max, 1);
}
void set(size_type i, const info_type& c) {
set({}, _max, 1, i, c);
}
void range_apply(size_type l, size_type r, const tag_type& c) {
range_apply({}, _max, 1, l, r, c);
}
void apply(size_type i, const tag_type& c) {
range_apply(i, i, c);
}
info_type range_query(size_type l, size_type r) {
return range_query({}, _max, 1, l, r);
}
info_type query(size_type i) {
return range_query(i, i);
}
Sequence serialize() {
Sequence res = {};
for (size_type i = 0; i <= _max; ++i) {
res.push_back(query(i));
}
return res;
}
const vector<info_type>& get_d() {
return d;
}
};
struct MaxTag {
ll val = -INFLL;
void apply(const MaxTag& rhs) {
if (rhs.val != -INFLL)
val = rhs.val;
}
};
struct MaxInfo {
ll val = -INFLL;
void apply(const MaxTag& rhs, size_t len) {
if (rhs.val != -INFLL)
val = rhs.val * len;
}
};
MaxInfo operator+(const MaxInfo &a, const MaxInfo &b) {
return {max(a.val, b.val)};
}
void solve() {
read(int, n, m, k);
readvec1(ll, a, n);
vector<map<int, vector<tiii>>> raw_ld(n + 1);
vector<int> sz(n + 1);
vector<set<int>> st(n + 1);
vector<unordered_map<int, int, safe_hash>> mp(n + 1);
vector<vector<short>> grid(n + 1, vector<short>(m + 1));
vector<vector<short>> x_diff(n + 1, vector<short>(m + 2)), y_diff(m + 1, vector<short>(n + 2));
while (k--) {
read(int, x1, y1, x2, y2, c);
raw_ld[x2][y2].emplace_back(x1, y1, c);
st[x1].emplace(y1);
st[x2].emplace(y2);
read(short, x1, y1, x2, y2);
if (x1 == x2) {
if (y1 > y2) swap(y1, y2);
x_diff[x1][y1] += 1;
x_diff[x1][y2 + 1] -= 1;
} else if (y1 == y2) {
if (x1 > x2) swap(x1, x2);
y_diff[y1][x1] += 1;
y_diff[y1][x2 + 1] -= 1;
}
}
st[1].emplace(1);
// tuple(y, x', y', profit)
vector<vector<pair<int, vector<tiii>>>> ld(n + 1);
vector<segtree<MaxInfo, MaxTag>> right_tr = {{0}}, left_tr = {{0}};
for (int i = 1; i <= n; ++i) {
for (auto&& [y, v] : raw_ld[i]) {
ld[i].emplace_back(y, v);
int curr = 0;
for (int j = 1; j <= m; ++j) {
curr += x_diff[i][j];
if (curr) grid[i][j] = 1;
}
int N = 0;
for (auto&& x : st[i]) mp[i][x] = ++N;
sz[i] = N;
right_tr.push_back(segtree<MaxInfo, MaxTag>(sz[i] + 1));
left_tr.push_back(segtree<MaxInfo, MaxTag>(sz[i] + 1));
}
left_tr[1].set(1, {a[1]});
right_tr[1].set(1, {-a[1]});
ll res = -INFLL;
for (int i = 2; i <= n; ++i) {
for (auto&& [y, v] : ld[i]) {
ll mx = -INFLL;
for (auto&& [x1, y1, profit] : v) {
// left
ll left = left_tr[x1].range_query(0, mp[x1][y1]).val;
if (left != -INFLL) {
mx = max(mx, left - a[x1] * y1 + profit);
}
// right
ll right = right_tr[x1].range_query(mp[x1][y1], sz[x1]).val;
if (right != -INFLL) {
mx = max(mx, right + a[x1] * y1 + profit);
for (int i = 1; i <= m; ++i) {
int curr = 0;
for (int j = 1; j <= n; ++j) {
curr += y_diff[i][j];
if (curr) grid[j][i] = 1;
}
}
// for (int i = 1; i <= n; ++i) {
// for (int j = 1; j <= m; ++j) {
// cerr << grid[i][j] << " \n"[j == m];
// }
// }
// cerr << endl;
read(short, sx, sy);
grid[sx][sy] = 2;
deque<pair<short, short>> q, nq;
q.emplace_back(sx, sy);
vector<vector<short>> t(n + 1, vector<short>(m + 1));
vector<vector<bool>> v(n + 1, vector<bool>(m + 1));
while (1) {
int f = 0;
// debug(endl);
while (q.size()) {
popfront(q, x, y);
// debug(make_tuple(x, y));
grid[x][y] = 2;
if (x - 1 >= 1) {
if (v[x - 1][y] == 0) {
if (grid[x - 1][y] == 0) {
q.emplace_back(x - 1, y);
} else if (grid[x - 1][y] == 1) {
nq.emplace_back(x - 1, y);
}
v[x - 1][y] = 1;
}
} else {
f = 1;
}
if (mx == -INFLL) continue;
ll raw_left = left_tr[i].query(mp[i][y]).val;
left_tr[i].set(mp[i][y], {max(raw_left, mx + y * a[i])});
ll raw_right = right_tr[i].query(mp[i][y]).val;
right_tr[i].set(mp[i][y], {max(raw_right, mx - y * a[i])});
if (i == n) {
res = max(res, mx - (m - y) * a[i]);
if (x + 1 <= n) {
if (v[x + 1][y] == 0) {
if (grid[x + 1][y] == 0) {
q.emplace_back(x + 1, y);
} else if (grid[x + 1][y] == 1) {
nq.emplace_back(x + 1, y);
}
v[x + 1][y] = 1;
}
} else {
f = 1;
}
if (y + 1 <= m) {
if (v[x][y + 1] == 0) {
if (grid[x][y + 1] == 0) {
q.emplace_back(x, y + 1);
} else if (grid[x][y + 1] == 1) {
nq.emplace_back(x, y + 1);
}
v[x][y + 1] = 1;
}
} else {
f = 1;
}
if (y - 1 >= 1) {
if (v[x][y - 1] == 0) {
if (grid[x][y - 1] == 0) {
q.emplace_back(x, y - 1);
} else if (grid[x][y - 1] == 1) {
nq.emplace_back(x, y - 1);
}
v[x][y - 1] = 1;
}
} else {
f = 1;
}
}
if (f) {
break;
} else {
swap(q, nq);
}
}
int res = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
// cerr << grid[i][j] << " \n"[j == m];
if (grid[i][j] == 0) {
res += 1;
}
}
}
if (res == -INFLL) {
cout << "NO ESCAPE\n";
} else {
cout << -res << '\n';
}
cout << res << '\n';
}
int main() {

View File

@ -1,22 +1,16 @@
4
5 3 3
5 17 8 1 4
1 3 3 3 4
3 1 5 2 5
3 2 5 1 6
6 3 3
5 17 8 1 4 2
1 3 3 3 4
3 1 5 2 5
3 2 5 1 6
5 3 1
5 17 8 1 4
1 3 5 3 100
5 5 5
3 2 3 7 5
3 5 4 2 1
2 2 5 4 5
4 4 5 2 3
1 2 4 2 2
3 3 5 2 4
17 17 14
2 2 2 13
2 2 7 2
2 7 9 7
7 2 7 7
9 7 9 13
2 13 9 13
11 2 11 7
11 2 16 2
16 2 16 7
16 7 11 7
4 15 4 17
4 15 12 15
12 15 12 9
12 9 17 9
8 9

View File

@ -496,7 +496,7 @@ int main() {
#if __cplusplus < 201402L or defined(_MSC_VER) and not defined(__clang__)
assert(false && "incompatible compiler variant detected.");
#endif
untie, cout.tie(NULL);
untie;
prep();
#ifdef SINGLE_TEST_CASE
solve();

View File

@ -1,3 +1,10 @@
/**
* Author: subcrip
* Created: 2024-06-01 13:45:49
* Modified: 2024-06-01 15:48:33
* Elapsed: 122 minutes
*/
#pragma GCC optimize("Ofast")
/////////////////////////////////////////////////////////
/**
@ -173,6 +180,7 @@ struct array_hash {
};
/* build data structures */
#define faster(um) __AS_PROCEDURE((um).reserve(1024); (um).max_load_factor(0.25);)
#define unordered_counter(from, to) __AS_PROCEDURE(unordered_map<__as_typeof(from), size_t, safe_hash> to; for (auto&& x : from) ++to[x];)
#define counter(from, to, cmp) __AS_PROCEDURE(map<__as_typeof(from), size_t, cmp> to; for (auto&& x : from) ++to[x];)
#define pa(a) __AS_PROCEDURE(__typeof(a) pa; pa.push_back({}); for (auto&&x : a) pa.push_back(pa.back() + x);)
@ -428,6 +436,9 @@ istream& operator>>(istream& in, MLLd& num) {
}
// miscancellous
#define functor(func) [&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);}
template <typename Func, typename RandomIt> void sort_by_key(RandomIt first, RandomIt last, Func extractor) {
std::sort(first, last, [&] (auto&& a, auto&& b) { return std::less<>()(extractor(a), extractor(b)); });
}
@ -472,12 +483,9 @@ public:
template <typename T> vector<pair<int, T>> enumerate(const vector<T>& container) {
return zip<int, T>(ArithmeticIterator<int>(0), ArithmeticIterator<int>(INT_MAX), container.begin(), container.end());
}
#define functor(func) [&](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);}
/////////////////////////////////////////////////////////
// #define SINGLE_TEST_CASE
#define SINGLE_TEST_CASE
// #define DUMP_TEST_CASE 7219
// #define TOT_TEST_CASE 10000
@ -488,32 +496,121 @@ void dump_ignore() {}
void prep() {
}
vector<int> factcount(int n) {
vector<bool> not_prime(n + 1);
vector<int> res(n + 1), num(n + 1);
res[1] = 1;
for (int i = 2; i <= n; ++i) {
if (not not_prime[i]) {
res[i] = 2;
num[i] = 1;
}
for (auto&& x : res) {
if (i * x > n) break;
not_prime[i * x] = 1;
if (i % x == 0) {
num[i * x] = num[i] + 1;
res[i * x] = res[i] / num[i * x] * (num[i * x] + 1);
break;
}
num[i * x] = 1;
res[i * x] = res[i] * 2;
void solve() {
read(int, n, m, k);
vector<vector<short>> grid(n + 1, vector<short>(m + 1));
vector<vector<short>> x_diff(n + 1, vector<short>(m + 2)), y_diff(m + 1, vector<short>(n + 2));
while (k--) {
read(short, x1, y1, x2, y2);
if (x1 == x2) {
if (y1 > y2) swap(y1, y2);
x_diff[x1][y1] += 1;
x_diff[x1][y2 + 1] -= 1;
} else if (y1 == y2) {
if (x1 > x2) swap(x1, x2);
y_diff[y1][x1] += 1;
y_diff[y1][x2 + 1] -= 1;
}
}
return res;
}
for (int i = 1; i <= n; ++i) {
int curr = 0;
for (int j = 1; j <= m; ++j) {
curr += x_diff[i][j];
if (curr) grid[i][j] = 1;
}
}
for (int i = 1; i <= m; ++i) {
int curr = 0;
for (int j = 1; j <= n; ++j) {
curr += y_diff[i][j];
if (curr) grid[j][i] = 1;
}
}
// for (int i = 1; i <= n; ++i) {
// for (int j = 1; j <= m; ++j) {
// cerr << grid[i][j] << " \n"[j == m];
// }
// }
// cerr << endl;
read(short, sx, sy);
grid[sx][sy] = 2;
deque<pair<short, short>> q, nq;
q.emplace_back(sx, sy);
vector<vector<short>> t(n + 1, vector<short>(m + 1));
vector<vector<bool>> v(n + 1, vector<bool>(m + 1));
while (1) {
int f = 0;
// debug(endl);
while (q.size()) {
popfront(q, x, y);
// debug(make_tuple(x, y));
grid[x][y] = 2;
if (x - 1 >= 1) {
if (v[x - 1][y] == 0) {
if (grid[x - 1][y] == 0) {
q.emplace_back(x - 1, y);
} else if (grid[x - 1][y] == 1) {
nq.emplace_back(x - 1, y);
}
v[x - 1][y] = 1;
}
} else {
f = 1;
}
if (x + 1 <= n) {
if (v[x + 1][y] == 0) {
if (grid[x + 1][y] == 0) {
q.emplace_back(x + 1, y);
} else if (grid[x + 1][y] == 1) {
nq.emplace_back(x + 1, y);
}
v[x + 1][y] = 1;
}
} else {
f = 1;
}
if (y + 1 <= m) {
if (v[x][y + 1] == 0) {
if (grid[x][y + 1] == 0) {
q.emplace_back(x, y + 1);
} else if (grid[x][y + 1] == 1) {
nq.emplace_back(x, y + 1);
}
v[x][y + 1] = 1;
}
} else {
f = 1;
}
if (y - 1 >= 1) {
if (v[x][y - 1] == 0) {
if (grid[x][y - 1] == 0) {
q.emplace_back(x, y - 1);
} else if (grid[x][y - 1] == 1) {
nq.emplace_back(x, y - 1);
}
v[x][y - 1] = 1;
}
} else {
f = 1;
}
void solve() {
cout << functor(std::min<int>)(1, 2);
}
if (f) {
break;
} else {
swap(q, nq);
}
}
int res = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
// cerr << grid[i][j] << " \n"[j == m];
if (grid[i][j] == 0) {
res += 1;
}
}
}
cout << res << '\n';
}
int main() {