Skip to content

Commit 0723563

Browse files
Add some example
1 parent 2fd337b commit 0723563

File tree

6 files changed

+884
-3
lines changed

6 files changed

+884
-3
lines changed

library/example/Luogu_P3372.cpp

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// mp-oi-library extension note: start. Do not modify this part.
2+
// mp-oi-library extension header: library version: @MrPython-0.2.6
3+
// mp-oi-library extension note: file bits.hpp
4+
#ifndef MP_LIBRARY_BITS
5+
#define MP_LIBRARY_BITS
6+
#include <limits>
7+
namespace mrpython {
8+
unsigned countl_zero(unsigned x) { return __builtin_clz(x); }
9+
unsigned countl_zero(unsigned long x) { return __builtin_clzl(x); }
10+
unsigned countl_zero(unsigned long long x) { return __builtin_clzll(x); }
11+
unsigned countr_zero(unsigned x) { return __builtin_ctz(x); }
12+
unsigned countr_zero(unsigned long x) { return __builtin_ctzl(x); }
13+
unsigned countr_zero(unsigned long long x) { return __builtin_ctzll(x); }
14+
unsigned int_log2(unsigned n) {
15+
return std::numeric_limits<unsigned>::digits - 1 - countl_zero(n);
16+
}
17+
unsigned long int_log2(unsigned long n) {
18+
return std::numeric_limits<unsigned long>::digits - 1 - countl_zero(n);
19+
}
20+
unsigned long long int_log2(unsigned long long n) {
21+
return std::numeric_limits<unsigned long long>::digits - 1 - countl_zero(n);
22+
}
23+
unsigned lowbit(unsigned x) { return x & -x; }
24+
unsigned long lowbit(unsigned long x) { return x & -x; }
25+
unsigned long long lowbit(unsigned long long x) { return x & -x; }
26+
unsigned highbit(unsigned x) { return (unsigned)1 << int_log2(x); }
27+
unsigned long highbit(unsigned long x) {
28+
return (unsigned long)1 << int_log2(x);
29+
}
30+
unsigned long long highbit(unsigned long long x) {
31+
return (unsigned long long)1 << int_log2(x);
32+
}
33+
} // namespace mrpython
34+
#endif
35+
// mp-oi-library extension note: file lazy_segment_tree.hpp
36+
37+
#ifndef MP_LIBRARY_LAZY_SEGMENT_TREE_HPP
38+
#define MP_LIBRARY_LAZY_SEGMENT_TREE_HPP
39+
#include <algorithm>
40+
#include <functional>
41+
#include <vector>
42+
43+
namespace mrpython {
44+
using std::size_t;
45+
template <typename T, typename MergeFunction, typename Lazy,
46+
typename OperateFunction, typename MergeLazyFunction>
47+
class lazy_segment_tree {
48+
std::vector<T> data;
49+
std::vector<Lazy> lazy;
50+
std::vector<size_t> size;
51+
size_t n;
52+
Lazy lazyInit;
53+
MergeFunction mergeData;
54+
OperateFunction operate;
55+
MergeLazyFunction mergeLazy;
56+
void build(void) {
57+
data.reserve(2 * n - 1), size.reserve(2 * n - 1);
58+
for (size_t i = n; i < 2 * n - 1; ++i) {
59+
size_t d = 2 * n - 1 - i;
60+
size_t l = d * 2, r = d * 2 + 1;
61+
data.emplace_back(mergeData(data[2 * n - 1 - l], data[2 * n - 1 - r]));
62+
size.emplace_back(size[2 * n - 1 - l] + size[2 * n - 1 - r]);
63+
}
64+
std::reverse(data.begin(), data.end());
65+
std::reverse(size.begin(), size.end());
66+
}
67+
void pushdown(size_t pos) {
68+
if (size[pos] == 1) {
69+
lazy[pos] = lazyInit;
70+
return;
71+
}
72+
add_tag_for_node(2 * pos + 1, lazy[pos]);
73+
add_tag_for_node(2 * pos + 2, lazy[pos]);
74+
lazy[pos] = lazyInit;
75+
}
76+
void add_tag_for_node(size_t pos, Lazy const& lazyVal) {
77+
data[pos] = operate(lazyVal, data[pos], size[pos]);
78+
lazy[pos] = mergeLazy(lazy[pos], lazyVal);
79+
}
80+
T get_impl(size_t l, size_t r, size_t pos) {
81+
if (l == 0 && r == size[pos]) return data[pos];
82+
pushdown(pos);
83+
size_t m = size[pos * 2 + 1];
84+
if (l < m && r > m)
85+
return mergeData(get_impl(l, m, pos * 2 + 1),
86+
get_impl(0, r - m, pos * 2 + 2));
87+
else if (l < m)
88+
return get_impl(l, r, pos * 2 + 1);
89+
else if (r > m)
90+
return get_impl(l - m, r - m, pos * 2 + 2);
91+
else
92+
__builtin_unreachable();
93+
}
94+
void set_impl(size_t l, size_t r, Lazy const& operateVal, size_t pos) {
95+
if (l == 0 && r == size[pos]) return add_tag_for_node(pos, operateVal);
96+
pushdown(pos);
97+
size_t m = size[pos * 2 + 1];
98+
if (l < m && r > m)
99+
set_impl(l, m, operateVal, pos * 2 + 1),
100+
set_impl(0, r - m, operateVal, pos * 2 + 2);
101+
else if (l < m)
102+
set_impl(l, r, operateVal, pos * 2 + 1);
103+
else if (r > m)
104+
set_impl(l - m, r - m, operateVal, pos * 2 + 2);
105+
else
106+
__builtin_unreachable();
107+
data[pos] = mergeData(data[pos * 2 + 1], data[pos * 2 + 2]);
108+
}
109+
110+
public:
111+
template <typename InputIterator>
112+
lazy_segment_tree(InputIterator first, InputIterator last,
113+
Lazy const& lazyInitVal,
114+
MergeFunction const& mergeDataFun = MergeFunction(),
115+
OperateFunction const& OperateFun = OperateFunction(),
116+
MergeLazyFunction const& mergeTagFun = MergeLazyFunction())
117+
: data(first, last),
118+
lazy(2 * data.size() - 1, lazyInitVal),
119+
size(data.size(), 1),
120+
n(data.size()),
121+
lazyInit(lazyInitVal),
122+
mergeData(mergeDataFun),
123+
operate(OperateFun),
124+
mergeLazy(mergeTagFun) {
125+
rotate(data.begin(), data.begin() + (2 * n - 1) - (highbit(2 * n - 1) - 1),
126+
data.end());
127+
reverse(data.begin(), data.end());
128+
build();
129+
}
130+
lazy_segment_tree(size_t len, T const& init, Lazy const& lazyInitVal,
131+
MergeFunction const& mergeDataFun = MergeFunction(),
132+
OperateFunction const& OperateFun = OperateFunction(),
133+
MergeLazyFunction const& mergeTagFun = MergeLazyFunction())
134+
: data(len, init),
135+
lazy(2 * len - 1, lazyInitVal),
136+
size(len, 1),
137+
n(len),
138+
lazyInit(lazyInitVal),
139+
mergeData(mergeDataFun),
140+
operate(OperateFun),
141+
mergeLazy(mergeTagFun) {
142+
build();
143+
}
144+
T get(size_t l, size_t r) { return get_impl(l, r, 0); }
145+
void set(size_t l, size_t r, Lazy const& operateVal) {
146+
set_impl(l, r, operateVal, 0);
147+
}
148+
};
149+
template <typename T> struct lazy_segment_tree_add_add_operate_function {
150+
T operator()(T const& lazy, T const& data, size_t size) const {
151+
return data + lazy * size;
152+
}
153+
};
154+
template <typename T>
155+
using lazy_segment_tree_add_add =
156+
lazy_segment_tree<T, std::plus<T>, T,
157+
lazy_segment_tree_add_add_operate_function<T>,
158+
std::plus<T>>;
159+
160+
template <typename NodeStruct> class lazy_segment_tree_from_node {
161+
using T = typename NodeStruct::T;
162+
using Lazy = typename NodeStruct::Lazy;
163+
struct MergeFunction {
164+
T operator()(T const& a, T const& b) const {
165+
return NodeStruct::merge_data(a, b);
166+
}
167+
};
168+
struct OperateFunction {
169+
T operator()(Lazy const& lazy, T const& data, size_t size) const {
170+
return NodeStruct::operate(lazy, data, size);
171+
}
172+
};
173+
struct MergeLazyFunction {
174+
Lazy operator()(Lazy const& a, Lazy const& b) const {
175+
return NodeStruct::merge_lazy(a, b);
176+
}
177+
};
178+
lazy_segment_tree_from_node() = delete;
179+
180+
public:
181+
using type = lazy_segment_tree<T, MergeFunction, Lazy, OperateFunction,
182+
MergeLazyFunction>;
183+
};
184+
} // namespace mrpython
185+
#endif
186+
187+
// mp-oi-library extension note: end
188+
#include <bits/stdc++.h>
189+
using namespace std;
190+
istream& fin = cin;
191+
ostream& fout = cout;
192+
using ui = unsigned int;
193+
using uli = unsigned long long int;
194+
using li = long long int;
195+
int main(void) {
196+
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
197+
size_t n, m;
198+
fin >> n >> m;
199+
vector<li> a(n);
200+
for (li& i : a) fin >> i;
201+
mrpython::lazy_segment_tree_add_add<li> tree(a.begin(), a.end(), 0);
202+
while (m--) {
203+
char op;
204+
size_t x, y;
205+
fin >> op >> x >> y;
206+
--x;
207+
if (op == '1') {
208+
size_t k;
209+
fin >> k;
210+
tree.set(x, y, k);
211+
}
212+
if (op == '2') { fout << tree.get(x, y) << '\n'; }
213+
}
214+
return 0;
215+
}

0 commit comments

Comments
 (0)