結果
問題 | No.2101 [Cherry Alpha N] ずっとこの数列だったらいいのに |
ユーザー | mai |
提出日時 | 2022-10-14 23:27:21 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 705 ms / 6,000 ms |
コード長 | 14,976 bytes |
コンパイル時間 | 4,496 ms |
コンパイル使用メモリ | 248,840 KB |
実行使用メモリ | 60,892 KB |
最終ジャッジ日時 | 2024-06-26 17:21:24 |
合計ジャッジ時間 | 28,701 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 3 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 391 ms
44,376 KB |
testcase_04 | AC | 435 ms
44,376 KB |
testcase_05 | AC | 263 ms
32,088 KB |
testcase_06 | AC | 391 ms
44,376 KB |
testcase_07 | AC | 475 ms
44,504 KB |
testcase_08 | AC | 424 ms
44,380 KB |
testcase_09 | AC | 216 ms
24,020 KB |
testcase_10 | AC | 193 ms
23,892 KB |
testcase_11 | AC | 297 ms
31,960 KB |
testcase_12 | AC | 437 ms
32,088 KB |
testcase_13 | AC | 255 ms
24,024 KB |
testcase_14 | AC | 149 ms
13,276 KB |
testcase_15 | AC | 618 ms
45,144 KB |
testcase_16 | AC | 463 ms
44,376 KB |
testcase_17 | AC | 121 ms
14,680 KB |
testcase_18 | AC | 631 ms
60,756 KB |
testcase_19 | AC | 653 ms
60,628 KB |
testcase_20 | AC | 705 ms
60,764 KB |
testcase_21 | AC | 649 ms
60,760 KB |
testcase_22 | AC | 642 ms
60,760 KB |
testcase_23 | AC | 651 ms
60,760 KB |
testcase_24 | AC | 644 ms
60,656 KB |
testcase_25 | AC | 646 ms
60,888 KB |
testcase_26 | AC | 650 ms
60,888 KB |
testcase_27 | AC | 633 ms
60,760 KB |
testcase_28 | AC | 631 ms
60,760 KB |
testcase_29 | AC | 644 ms
60,764 KB |
testcase_30 | AC | 641 ms
60,760 KB |
testcase_31 | AC | 699 ms
60,760 KB |
testcase_32 | AC | 625 ms
60,760 KB |
testcase_33 | AC | 445 ms
60,760 KB |
testcase_34 | AC | 448 ms
60,760 KB |
testcase_35 | AC | 454 ms
60,884 KB |
testcase_36 | AC | 454 ms
60,892 KB |
testcase_37 | AC | 454 ms
60,760 KB |
testcase_38 | AC | 30 ms
11,608 KB |
testcase_39 | AC | 121 ms
15,316 KB |
testcase_40 | AC | 243 ms
60,760 KB |
testcase_41 | AC | 2 ms
5,376 KB |
ソースコード
#pragma GCC optimize("O3") #include <bits/stdc++.h> // clang-format off using namespace std; using ll = long long int; #define all(v) (v).begin(),(v).end() #define repeat(cnt,l) for(typename remove_const<typename remove_reference<decltype(l)>::type>::type cnt={};(cnt)<(l);++(cnt)) #define rrepeat(cnt,l) for(auto cnt=(l)-1;0<=(cnt);--(cnt)) #define iterate(cnt,b,e) for(auto cnt=(b);(cnt)!=(e);++(cnt)) #define upto(cnt,b,e,step) for(auto cnt=(b);(cnt)<=(e);(cnt)+=(step)) #define downto(cnt,b,e,step) for(auto cnt=(b);(e)<=(cnt);(cnt)-=(step)) const long long MD = 998244353; const long double PI = 3.1415926535897932384626433832795L; template<typename T1, typename T2> inline ostream& operator <<(ostream &o, const pair<T1, T2> p) { o << '(' << p.first << ':' << p.second << ')'; return o; } template<typename T> inline T& chmax(T& to, const T& val) { return to = max(to, val); } template<typename T> inline T& chmin(T& to, const T& val) { return to = min(to, val); } void bye(string s, int code = 0) { cout << s << endl; exit(code); } mt19937_64 randdev(8901016); template<typename T, typename Random = decltype(randdev), typename enable_if<is_integral<T>::value>::type* = nullptr> inline T rand(T l, T h, Random& rand = randdev) { return uniform_int_distribution<T>(l, h)(rand); } template<typename T, typename Random = decltype(randdev), typename enable_if<is_floating_point<T>::value>::type* = nullptr> inline T rand(T l, T h, Random& rand = randdev) { return uniform_real_distribution<T>(l, h)(rand); }template<typename T> static ostream& operator<<(ostream& o, const std::vector<T>& v) { o << "[ "; for(const auto& e : v) o<<e<<' '; return o << ']'; } template <typename I> struct MyRangeFormat{ I b,e; MyRangeFormat(I _b, I _e):b(_b),e(_e){} }; template<typename I> static ostream& operator<<(ostream& o, const MyRangeFormat<I>& f) { o << "[ "; iterate(i,f.b,f.e) o<<*i<<' '; return o << ']'; } template <typename I> struct MyMatrixFormat{ const I& p; long long n, m; MyMatrixFormat(const I& _p, long long _n, long long _m):p(_p),n(_n),m(_m){} }; template<typename I> static ostream& operator<<(ostream& o, const MyMatrixFormat<I>& f) { o<<'\n'; repeat(i,(f.n)) { repeat(j,f.m) o<<f.p[i][j]<<' '; o<<'\n'; } return o; } struct LOG_t { ~LOG_t() { cout << endl; } }; #define LOG (LOG_t(),cout<<'L'<<__LINE__<<": ") #define FMTA(m,w) (MyRangeFormat<decltype(m+0)>(m,m+w)) #define FMTR(b,e) (MyRangeFormat<decltype(e)>(b,e)) #define FMTV(v) FMTR(v.begin(),v.end()) #define FMTM(m,h,w) (MyMatrixFormat<decltype(m+0)>(m,h,w)) #if defined(_WIN32) || defined(_WIN64) #define getc_x _getc_nolock #define putc_x _putc_nolock #elif defined(__GNUC__) #define getc_x getc_unlocked #define putc_x putc_unlocked #else #define getc_x getc #define putc_x putc #endif class MaiScanner { FILE* fp_; constexpr bool isvisiblechar(char c) noexcept { return (0x21<=(c)&&(c)<=0x7E); } public: inline MaiScanner(FILE* fp):fp_(fp){} template<typename T> void input_integer(T& var) noexcept { var = 0; T sign = 1; int cc = getc_x(fp_); for (; cc < '0' || '9' < cc; cc = getc_x(fp_)) if (cc == '-') sign = -1; for (; '0' <= cc && cc <= '9'; cc = getc_x(fp_)) var = (var << 3) + (var << 1) + cc - '0'; var = var * sign; } inline int c() noexcept { return getc_x(fp_); } template<typename T, typename enable_if<is_integral<T>::value, nullptr_t>::type = nullptr> inline MaiScanner& operator>>(T& var) noexcept { input_integer<T>(var); return *this; } inline MaiScanner& operator>>(string& var) { int cc = getc_x(fp_); for (; !isvisiblechar(cc); cc = getc_x(fp_)); for (; isvisiblechar(cc); cc = getc_x(fp_)) var.push_back(cc); return *this; } template<typename IT> inline void in(IT begin, IT end) { for (auto it = begin; it != end; ++it) *this >> *it; } }; class MaiPrinter { FILE* fp_; public: inline MaiPrinter(FILE* fp):fp_(fp){} template<typename T> void output_integer(T var) noexcept { if (var == 0) { putc_x('0', fp_); return; } if (var < 0) putc_x('-', fp_), var = -var; char stack[32]; int stack_p = 0; while (var) stack[stack_p++] = '0' + (var % 10), var /= 10; while (stack_p) putc_x(stack[--stack_p], fp_); } inline MaiPrinter& operator<<(char c) noexcept { putc_x(c, fp_); return *this; } template<typename T, typename enable_if<is_integral<T>::value, nullptr_t>::type = nullptr> inline MaiPrinter& operator<<(T var) noexcept { output_integer<T>(var); return *this; } inline MaiPrinter& operator<<(const char* str_p) noexcept { while (*str_p) putc_x(*(str_p++), fp_); return *this; } inline MaiPrinter& operator<<(const string& str) { const char* p = str.c_str(); const char* l = p + str.size(); while (p < l) putc_x(*p++, fp_); return *this; } template<typename IT> void join(IT begin, IT end, char sep = ' ') { for (bool b = 0; begin != end; ++begin, b = 1) b ? *this << sep << *begin : *this << *begin; } }; MaiScanner scanner(stdin); MaiPrinter printer(stdout); // clang-format on template <typename T> // using T = ll; class SegmentTree { public: struct IdxVal { int index; T value; inline IdxVal(int _i = 0, const T& _v = T()) : index(_i), value(_v) {} inline void set(int i, const T& v) { index = i; value = v; } inline bool operator<(const T& t) const { return value < t; } inline bool operator==(const T& t) const { return value == t; } inline bool operator<(const IdxVal& iv) const { return value < iv.value || (value == iv.value && index < iv.index); } inline bool operator==(const IdxVal& iv) const { return index == iv.index && value == iv.value; } }; enum struct Cmd { None, Add, Flat }; struct Node { T sum, lazyValue; IdxVal max; Cmd lazyType; }; private: const int size_; vector<T> leaf_data_; vector<Node> node_data_; T* leaf_; Node* node_; void _resize() { leaf_data_.resize(size_); node_data_.resize(size_ - 1); leaf_ = &leaf_data_[0]; node_ = &node_data_[0] - 1; } void _init() { for (int i = size_ - 1; 0 < i; --i) { int c = i << 1; if (size_ <= c) node_[i].max.set(c - size_, leaf_[c - size_]); else node_[i].max = node_[c].max; node_[i].lazyType = Cmd::None; node_[i].sum = node_[i].lazyValue = 0; } } public: inline void fill(T val) { std::fill(leaf_data_.begin(), leaf_data_.end(), val); _init(); } SegmentTree(int _n) : size_([](int _n) { int s = 8; while (s < _n) s <<= 1; return s; }(_n)) { _resize(); _init(); } SegmentTree(int _n, const T& _fillVal) : size_([](int _n) { int s = 8; while (s < _n) s <<= 1; return s; }(_n)) { _resize(); fill(_fillVal); } private: // lazyを適応する(子を呼ぶ前に呼ぶ) // width: ptrが担当するnodeの範囲の大きさ(ptr = 1 ならば size_) inline void _applyDown(int ptr, int width) { width >>= 1; // if (size_ <= ptr) return; if (node_[ptr].lazyType == Cmd::Add) { int c = ptr << 1; if (size_ <= c) { leaf_[c - size_] += node_[ptr].lazyValue; leaf_[c + 1 - size_] += node_[ptr].lazyValue; } else { node_[c].sum += node_[ptr].lazyValue * width; node_[c].max.value += node_[ptr].lazyValue; node_[c].lazyValue += node_[ptr].lazyValue; if (node_[c].lazyType == Cmd::None) node_[c].lazyType = Cmd::Add; node_[c + 1].sum += node_[ptr].lazyValue * width; node_[c + 1].max.value += node_[ptr].lazyValue; node_[c + 1].lazyValue += node_[ptr].lazyValue; if (node_[c + 1].lazyType == Cmd::None) node_[c + 1].lazyType = Cmd::Add; } node_[ptr].lazyType = Cmd::None; node_[ptr].lazyValue = 0; } else if (node_[ptr].lazyType == Cmd::Flat) { node_[ptr].lazyType = Cmd::None; int c = ptr << 1; if (size_ <= c) { leaf_[c - size_] = node_[ptr].lazyValue; leaf_[c + 1 - size_] = node_[ptr].lazyValue; } else { node_[c].sum = node_[ptr].lazyValue * width; node_[c].max.value = node_[ptr].lazyValue; node_[c].lazyValue = node_[ptr].lazyValue; node_[c].lazyType = Cmd::Flat; node_[c + 1].sum = node_[ptr].lazyValue * width; node_[c + 1].max.value = node_[ptr].lazyValue; node_[c + 1].lazyValue = node_[ptr].lazyValue; node_[c + 1].lazyType = Cmd::Flat; } node_[ptr].lazyType = Cmd::None; node_[ptr].lazyValue = 0; } } // lazyを適応する(子を呼んだ後に呼ぶ) inline void _applyUp(int ptr) { if (size_ <= ptr << 1) { int i = (ptr << 1) - size_; if (leaf_[i] < leaf_[i + 1]) node_[ptr].max.set(i + 1, leaf_[i + 1]); else node_[ptr].max.set(i, leaf_[i]); node_[ptr].sum = leaf_[i] + leaf_[i + 1]; } else { if (node_[(ptr << 1)].max.value < node_[(ptr << 1) + 1].max.value) node_[ptr].max = node_[(ptr << 1) + 1].max; else node_[ptr].max = node_[(ptr << 1)].max; node_[ptr].sum = node_[ptr << 1].sum + node_[(ptr << 1) + 1].sum; } } // _downward_applyDown(ptr1): leaf[ptr1]の値を正しくする. void _downward_applyDown(int ptr1, int width = 1) { if (1 < ptr1) _downward_applyDown(ptr1 >> 1, width << 1); _applyDown(ptr1, width); } void _setValueRange(int begin, int end, T val, int ptr, int rangebegin, int rangeend) { if (rangeend <= begin || end <= rangebegin) return; // note:範囲外 if (begin <= rangebegin && rangeend <= end) { if (size_ <= ptr) { leaf_[rangebegin] = val; } else { node_[ptr].sum = val * (rangeend - rangebegin); node_[ptr].max.value = val; node_[ptr].lazyType = Cmd::Flat; node_[ptr].lazyValue = val; } return; } _applyDown(ptr, rangeend - rangebegin); _setValueRange(begin, end, val, ptr << 1, rangebegin, (rangebegin + rangeend) >> 1); _setValueRange(begin, end, val, (ptr << 1) + 1, (rangebegin + rangeend) >> 1, rangeend); _applyUp(ptr); } void _addValueRange(int begin, int end, T val, int ptr, int rangebegin, int rangeend) { if (rangeend <= begin || end <= rangebegin) return; // note:範囲外 if (begin <= rangebegin && rangeend <= end) { if (size_ <= ptr) { leaf_[rangebegin] += val; } else { node_[ptr].sum += val * (rangeend - rangebegin); node_[ptr].max.value += val; node_[ptr].lazyValue += val; if (node_[ptr].lazyType == Cmd::None) node_[ptr].lazyType = Cmd::Add; } return; } _applyDown(ptr, rangeend - rangebegin); _addValueRange(begin, end, val, ptr << 1, rangebegin, (rangebegin + rangeend) >> 1); _addValueRange(begin, end, val, (ptr << 1) + 1, (rangebegin + rangeend) >> 1, rangeend); _applyUp(ptr); } T _getSumRange(int begin, int end, int ptr, int rangebegin, int rangeend) { if (rangeend <= begin || end <= rangebegin) return 0; // note:範囲外 if (begin <= rangebegin && rangeend <= end) { if (size_ <= ptr) return leaf_[rangebegin]; else return node_[ptr].sum; } _applyDown(ptr, rangeend - rangebegin); return _getSumRange(begin, end, ptr << 1, rangebegin, (rangebegin + rangeend) >> 1) + _getSumRange(begin, end, (ptr << 1) + 1, (rangebegin + rangeend) >> 1, rangeend); } IdxVal _getMaxRange(int begin, int end, int ptr, int rangebegin, int rangeend) { if (rangeend <= begin || end <= rangebegin) return IdxVal(-1); // note:範囲外 if (begin <= rangebegin && rangeend <= end) { if (size_ <= ptr) return IdxVal(rangebegin, leaf_[rangebegin]); else return node_[ptr].max; } _applyDown(ptr, rangeend - rangebegin); auto l = _getMaxRange(begin, end, ptr << 1, rangebegin, (rangebegin + rangeend) >> 1); auto r = _getMaxRange(begin, end, (ptr << 1) + 1, (rangebegin + rangeend) >> 1, rangeend); if (l.index == -1) return move(r); if (r.index == -1) return move(l); return l.value < r.value ? move(r) : move(l); } public: // [index] の値を求める inline T getValue(int index) { _downward_applyDown((index + size_) >> 1); return leaf_[index]; } // [index] の値を書き換える inline void setValue(int index, T val) { _downward_applyDown((index + size_) >> 1); T diff = val - leaf_[index]; leaf_[index] = val; for (int ptr = (index + size_); 1 < ptr;) { ptr >>= 1; node_[ptr].sum -= diff; _applyUp(ptr); } } // [index] の値に加算する inline void addValue(int index, T val) { _downward_applyDown((index + size_) >> 1); leaf_[index] += val; for (int ptr = (index + size_); 1 < ptr;) { ptr >>= 1; node_[ptr].sum += val; _applyUp(ptr); } } // 区間[begin,end)全てにvalをセットする inline void setValueRange(int begin, int end, T val) { _setValueRange(begin, end, val, 1, 0, size_); } // 区間[begin,end)に一様にvalを加算する inline void addValueRange(int begin, int end, T val) { _addValueRange(begin, end, val, 1, 0, size_); } // 区間[begin,end)の和を求める inline T getSumRange(int begin, int end) { return _getSumRange(begin, end, 1, 0, size_); } // 区間[begin,end)の最大値とその位置を求める inline IdxVal getMaxRange(int begin, int end) { return _getMaxRange(begin, end, 1, 0, size_); } }; // int N, Q; ll A[200010]; pair<int, int> queries[200010]; ll results[200010]; // vector<pair<int, tuple<int, int, ll, ll>>> events; int main() { scanner >> N; SegmentTree<ll> seg_static(N); SegmentTree<ll> seg_slope(N); repeat(i, N) { int a, t; scanner >> a >> t; t -= 1; seg_static.setValue(i, a); events.emplace_back(t, make_tuple(1, i, ll(a + t), 0ll)); // 減少し始める events.emplace_back(t+a, make_tuple(3, i, 0ll, 0ll)); // これ以上減少しない } scanner >> Q; repeat(i, Q) { int d, l, r; scanner >> d >> l >> r; --l; events.emplace_back(d, make_tuple(2, i, ll(l), ll(r))); // query } sort(all(events)); for (auto event : events) { ll t = event.first; int etype, idx; ll e1, e2; tie(etype, idx, e1, e2) = event.second; if (etype == 1) { seg_static.setValue(idx, e1); seg_slope.setValue(idx, 1); } else if (etype == 3) { seg_static.setValue(idx, 0); seg_slope.setValue(idx, 0); } else if (etype == 2) { ll a = seg_slope.getSumRange(e1, e2); ll b = seg_static.getSumRange(e1, e2); results[idx] = b - t*a; } } repeat(i, Q) { printer << results[i] << '\n'; } return 0; }