結果
問題 | No.2988 Min-Plus Convolution Query |
ユーザー |
![]() |
提出日時 | 2024-12-20 09:54:43 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,466 ms / 2,000 ms |
コード長 | 12,308 bytes |
コンパイル時間 | 7,725 ms |
コンパイル使用メモリ | 322,384 KB |
実行使用メモリ | 126,608 KB |
最終ジャッジ日時 | 2024-12-20 09:55:27 |
合計ジャッジ時間 | 38,248 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 40 |
ソースコード
#line 1 "library/Template/template.hpp"#include <bits/stdc++.h>using namespace std;#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)#define ALL(v) (v).begin(), (v).end()#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())#define SZ(v) (int)v.size()#define MIN(v) *min_element(ALL(v))#define MAX(v) *max_element(ALL(v))#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())using uint = unsigned int;using ll = long long int;using ull = unsigned long long;using i128 = __int128_t;using u128 = __uint128_t;const int inf = 0x3fffffff;const ll INF = 0x1fffffffffffffff;template <typename T> inline bool chmax(T &a, T b) {if (a < b) {a = b;return 1;}return 0;}template <typename T> inline bool chmin(T &a, T b) {if (a > b) {a = b;return 1;}return 0;}template <typename T, typename U> T ceil(T x, U y) {assert(y != 0);if (y < 0)x = -x, y = -y;return (x > 0 ? (x + y - 1) / y : x / y);}template <typename T, typename U> T floor(T x, U y) {assert(y != 0);if (y < 0)x = -x, y = -y;return (x > 0 ? x / y : (x - y + 1) / y);}template <typename T> int popcnt(T x) {return __builtin_popcountll(x);}template <typename T> int topbit(T x) {return (x == 0 ? -1 : 63 - __builtin_clzll(x));}template <typename T> int lowbit(T x) {return (x == 0 ? -1 : __builtin_ctzll(x));}template <class T, class U>ostream &operator<<(ostream &os, const pair<T, U> &p) {os << "P(" << p.first << ", " << p.second << ")";return os;}template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {os << "{";for (int i = 0; i < vec.size(); i++) {os << vec[i] << (i + 1 == vec.size() ? "" : ", ");}os << "}";return os;}template <typename T, typename U>ostream &operator<<(ostream &os, const map<T, U> &map_var) {os << "{";for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {os << "(" << itr->first << ", " << itr->second << ")";itr++;if (itr != map_var.end())os << ", ";itr--;}os << "}";return os;}template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {os << "{";for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {os << *itr;++itr;if (itr != set_var.end())os << ", ";itr--;}os << "}";return os;}#ifdef LOCAL#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)#else#define show(...) true#endiftemplate <typename T> void _show(int i, T name) {cerr << '\n';}template <typename T1, typename T2, typename... T3>void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {for (; a[i] != ',' && a[i] != '\0'; i++)cerr << a[i];cerr << ":" << b << " ";_show(i + 1, a, c...);}#line 2 "library/Utility/fastio.hpp"#include <unistd.h>namespace fastio {static constexpr uint32_t SZ = 1 << 17;char ibuf[SZ];char obuf[SZ];char out[100];// pointer of ibuf, obufuint32_t pil = 0, pir = 0, por = 0;struct Pre {char num[10000][4];constexpr Pre() : num() {for (int i = 0; i < 10000; i++) {int n = i;for (int j = 3; j >= 0; j--) {num[i][j] = n % 10 | '0';n /= 10;}}}} constexpr pre;inline void load() {memmove(ibuf, ibuf + pil, pir - pil);pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);pil = 0;if (pir < SZ)ibuf[pir++] = '\n';}inline void flush() {fwrite(obuf, 1, por, stdout);por = 0;}void rd(char &c) {do {if (pil + 1 > pir)load();c = ibuf[pil++];} while (isspace(c));}void rd(string &x) {x.clear();char c;do {if (pil + 1 > pir)load();c = ibuf[pil++];} while (isspace(c));do {x += c;if (pil == pir)load();c = ibuf[pil++];} while (!isspace(c));}template <typename T> void rd_real(T &x) {string s;rd(s);x = stod(s);}template <typename T> void rd_integer(T &x) {if (pil + 100 > pir)load();char c;doc = ibuf[pil++];while (c < '-');bool minus = 0;if constexpr (is_signed<T>::value || is_same_v<T, i128>) {if (c == '-') {minus = 1, c = ibuf[pil++];}}x = 0;while ('0' <= c) {x = x * 10 + (c & 15), c = ibuf[pil++];}if constexpr (is_signed<T>::value || is_same_v<T, i128>) {if (minus)x = -x;}}void rd(int &x) {rd_integer(x);}void rd(ll &x) {rd_integer(x);}void rd(i128 &x) {rd_integer(x);}void rd(uint &x) {rd_integer(x);}void rd(ull &x) {rd_integer(x);}void rd(u128 &x) {rd_integer(x);}void rd(double &x) {rd_real(x);}void rd(long double &x) {rd_real(x);}template <class T, class U> void rd(pair<T, U> &p) {return rd(p.first), rd(p.second);}template <size_t N = 0, typename T> void rd_tuple(T &t) {if constexpr (N < std::tuple_size<T>::value) {auto &x = std::get<N>(t);rd(x);rd_tuple<N + 1>(t);}}template <class... T> void rd(tuple<T...> &tpl) {rd_tuple(tpl);}template <size_t N = 0, typename T> void rd(array<T, N> &x) {for (auto &d : x)rd(d);}template <class T> void rd(vector<T> &x) {for (auto &d : x)rd(d);}void read() {}template <class H, class... T> void read(H &h, T &...t) {rd(h), read(t...);}void wt(const char c) {if (por == SZ)flush();obuf[por++] = c;}void wt(const string s) {for (char c : s)wt(c);}void wt(const char *s) {size_t len = strlen(s);for (size_t i = 0; i < len; i++)wt(s[i]);}template <typename T> void wt_integer(T x) {if (por > SZ - 100)flush();if (x < 0) {obuf[por++] = '-', x = -x;}int outi;for (outi = 96; x >= 10000; outi -= 4) {memcpy(out + outi, pre.num[x % 10000], 4);x /= 10000;}if (x >= 1000) {memcpy(obuf + por, pre.num[x], 4);por += 4;} else if (x >= 100) {memcpy(obuf + por, pre.num[x] + 1, 3);por += 3;} else if (x >= 10) {int q = (x * 103) >> 10;obuf[por] = q | '0';obuf[por + 1] = (x - q * 10) | '0';por += 2;} elseobuf[por++] = x | '0';memcpy(obuf + por, out + outi + 4, 96 - outi);por += 96 - outi;}template <typename T> void wt_real(T x) {ostringstream oss;oss << fixed << setprecision(15) << double(x);string s = oss.str();wt(s);}void wt(int x) {wt_integer(x);}void wt(ll x) {wt_integer(x);}void wt(i128 x) {wt_integer(x);}void wt(uint x) {wt_integer(x);}void wt(ull x) {wt_integer(x);}void wt(u128 x) {wt_integer(x);}void wt(double x) {wt_real(x);}void wt(long double x) {wt_real(x);}template <class T, class U> void wt(const pair<T, U> val) {wt(val.first);wt(' ');wt(val.second);}template <size_t N = 0, typename T> void wt_tuple(const T t) {if constexpr (N < std::tuple_size<T>::value) {if constexpr (N > 0) {wt(' ');}const auto x = std::get<N>(t);wt(x);wt_tuple<N + 1>(t);}}template <class... T> void wt(tuple<T...> tpl) {wt_tuple(tpl);}template <class T, size_t S> void wt(const array<T, S> val) {auto n = val.size();for (size_t i = 0; i < n; i++) {if (i)wt(' ');wt(val[i]);}}template <class T> void wt(const vector<T> val) {auto n = val.size();for (size_t i = 0; i < n; i++) {if (i)wt(' ');wt(val[i]);}}void print() {wt('\n');}template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {wt(head);if (sizeof...(Tail))wt(' ');print(forward<Tail>(tail)...);}void __attribute__((destructor)) _d() {flush();}} // namespace fastiousing fastio::flush;using fastio::print;using fastio::read;inline void first(bool i = true) {print(i ? "first" : "second");}inline void Alice(bool i = true) {print(i ? "Alice" : "Bob");}inline void Takahashi(bool i = true) {print(i ? "Takahashi" : "Aoki");}inline void yes(bool i = true) {print(i ? "yes" : "no");}inline void Yes(bool i = true) {print(i ? "Yes" : "No");}inline void No() {print("No");}inline void YES(bool i = true) {print(i ? "YES" : "NO");}inline void NO() {print("NO");}inline void Yay(bool i = true) {print(i ? "Yay!" : ":(");}inline void Possible(bool i = true) {print(i ? "Possible" : "Impossible");}inline void POSSIBLE(bool i = true) {print(i ? "POSSIBLE" : "IMPOSSIBLE");}/*** @brief Fast IO*/#line 3 "sol.cpp"#line 2 "library/Algorithm/monotoneminima.hpp"template<typename F>vector<int> MonotoneMinima(int R,int C,F cmp){// cmp(i,j,k) := compare A[i,j] and A[i,k] (A[i,j] -> false, A[i,k] -> true)vector<int> ret(R);auto rec=[&](auto& f,vector<int> target)->void{int m=target.size();if(m==0)return;vector<int> even;for(int i=1;i<m;i+=2)even.push_back(target[i]);f(f,even);int cur=0;for(int i=0;i<m;i+=2){ret[target[i]]=cur;int end=C-1;if(i!=m-1)end=ret[even[i/2]];while(cur<end){cur++;if(cmp(target[i],ret[target[i]],cur))ret[target[i]]=cur;}}};vector<int> tmp(R);iota(ALL(tmp),0);rec(rec,tmp);return ret;}/*** @brief Monotone Minima* @docs docs/monotoneminima.md*/#line 5 "sol.cpp"int main() {int n, Q;read(n, Q);vector<int> a(n), b(n);read(a, b);int M = 1;while (M < Q)M <<= 1;using P = pair<int, int>;vector<vector<P>> seg(n);vector<vector<P>> qs(M * 2); // {k, index of query}rep(i, 0, n) {seg[i].push_back({0, a[i]});}rep(i, 0, Q) {int p, x, k;read(p, x, k);p--, k -= 2;seg[p].push_back({i, x});qs[i + M].push_back({k, i});}rrep(i, 1, M) {qs[i] = qs[i * 2];qs[i].insert(qs[i].end(), ALL(qs[i * 2 + 1]));}vector<vector<P>> vs(M * 2); // {index of A,value of A}auto add = [&](auto &add, int a, int b, P x, int cur = 1, int L = 0,int R = -1) -> void {if (R == -1)R = M;if (R <= a or b <= L)return;if (a <= L and R <= b) {vs[cur].push_back(x);return;}int mid = (L + R) >> 1;add(add, a, b, x, cur * 2, L, mid);add(add, a, b, x, cur * 2 + 1, mid, R);};rep(i, 0, n) {seg[i].push_back({Q, -1});rep(j, 0, SZ(seg[i]) - 1) {int L = seg[i][j].first, R = seg[i][j + 1].first;if (L >= R)continue;int x = seg[i][j].second;add(add, L, R, P{i, x});}}vector<ll> ret(Q, INF);rep(node, 1, M * 2) {if (vs[node].empty() or qs[node].empty())continue;sort(ALL(vs[node]));sort(ALL(qs[node]));show(vs[node], qs[node]);auto get = [&](int i, int j) -> ll {int diff = qs[node][i].first - vs[node][j].first;if (diff < 0)return INF - diff;if (diff >= n)return INF + diff;return vs[node][j].second + b[diff];};auto ch = [&](int i, int j, int k) -> bool {return get(i, j) >= get(i, k);};int R = SZ(qs[node]), C = SZ(vs[node]);auto ids = MonotoneMinima(R, C, ch);show(node, ids);rep(i, 0, R) chmin(ret[qs[node][i].second], get(i, ids[i]));}rep(i, 0, Q) print(ret[i]);return 0;}