Skip to content

Commit 77c0ecb

Browse files
authored
Create zkw.h
1 parent 08c0156 commit 77c0ecb

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

zkw.h

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
2+
/**
3+
* ZKWSegmentTree
4+
* All the query indices should be [first, last), starting from zero is ok.
5+
* Infinity rearranged from https://www.cnblogs.com/Judge/p/9514862.html
6+
*/
7+
template<typename T = int>
8+
class ZKWSegmentTree
9+
{
10+
public:
11+
12+
ZKWSegmentTree(int n)
13+
{
14+
initialize(n);
15+
}
16+
17+
template<typename RAIt>
18+
void assign(RAIt first, RAIt last)
19+
{
20+
initialize(last - first);
21+
copy(first, last, &sum_[n + 1]), copy(first, last, &min_[n + 1]), copy(first, last, &max_[n + 1]);
22+
build();
23+
}
24+
25+
void add(int x, int delta)
26+
{
27+
++x;
28+
int t = 0;
29+
x += n, max_[x] += delta, min_[x] += delta, sum_[x] += delta;
30+
for (; x > 1; x >>= 1) {
31+
sum_[x] += delta;
32+
t = ::min(min_[x], min_[x ^ 1]), min_[x] -= t, min_[x ^ 1] -= t, min_[x >> 1] += t;
33+
t = ::max(max_[x], max_[x ^ 1]), max_[x] -= t, max_[x ^ 1] -= t, max_[x >> 1] += t;
34+
}
35+
}
36+
37+
void add(int s, int t, int delta)
38+
{
39+
++s;
40+
int A = 0, lc = 0, rc = 0, len = 1;
41+
for (s += n - 1, t += n + 1; s ^ t ^ 1; s >>= 1, t >>= 1, len <<= 1) {
42+
if ((s & 1) ^ 1) add_[s ^ 1] += delta, lc += len, min_[s ^ 1] += delta, max_[s ^ 1] += delta;
43+
if (t & 1) add_[t ^ 1] += delta, rc += len, min_[t ^ 1] += delta, max_[t ^ 1] += delta;
44+
sum_[s >> 1] += delta * lc, sum_[t >> 1] += delta * rc;
45+
A = ::min(min_[s], min_[s ^ 1]), min_[s] -= A, min_[s ^ 1] -= A, min_[s >> 1] += A,
46+
A = ::min(min_[t], min_[t ^ 1]), min_[t] -= A, min_[t ^ 1] -= A, min_[t >> 1] += A;
47+
A = ::max(max_[s], max_[s ^ 1]), max_[s] -= A, max_[s ^ 1] -= A, max_[s >> 1] += A,
48+
A = ::max(max_[t], max_[t ^ 1]), max_[t] -= A, max_[t ^ 1] -= A, max_[t >> 1] += A;
49+
}
50+
for (lc += rc; s > 1; s >>= 1) {
51+
sum_[s >> 1] += delta * lc;
52+
A = ::min(min_[s], min_[s ^ 1]), min_[s] -= A, min_[s ^ 1] -= A, min_[s >> 1] += A,
53+
A = ::max(max_[s], max_[s ^ 1]), max_[s] -= A, max_[s ^ 1] -= A, max_[s >> 1] += A;
54+
}
55+
}
56+
57+
int sum(int s, int t)
58+
{
59+
++s;
60+
int lc = 0, rc = 0, len = 1, ans = 0;
61+
for (s += n - 1, t += n + 1; s ^ t ^ 1; s >>= 1, t >>= 1, len <<= 1) {
62+
if ((s & 1) ^ 1) ans += sum_[s ^ 1] + len * add_[s ^ 1], lc += len;
63+
if (t & 1) ans += sum_[t ^ 1] + len * add_[t ^ 1], rc += len;
64+
if (add_[s >> 1]) ans += add_[s >> 1] * lc;
65+
if (add_[t >> 1]) ans += add_[t >> 1] * rc;
66+
}
67+
for (lc += rc, s >>= 1; s; s >>= 1) if (add_[s]) ans += add_[s] * lc;
68+
return ans;
69+
}
70+
71+
int min(int s, int t)
72+
{
73+
++s;
74+
int L = 0, R = 0, ans = 0;
75+
if (s == t) return query_node(s);
76+
for (s += n, t += n; s ^ t ^ 1; s >>= 1, t >>= 1) {
77+
L += min_[s], R += min_[t];
78+
if ((s & 1) ^ 1) L = ::min(L, min_[s ^ 1]);
79+
if (t & 1) R = ::min(R, min_[t ^ 1]);
80+
}
81+
for (ans = ::min(L, R), s >>= 1; s; s >>= 1) ans += min_[s];
82+
return ans;
83+
}
84+
85+
int max(int s, int t)
86+
{
87+
++s;
88+
int L = 0, R = 0, ans = 0;
89+
if (s == t) return query_node(s);
90+
for (s += n, t += n; s ^ t ^ 1; s >>= 1, t >>= 1) {
91+
L += max_[s], R += max_[t];
92+
if ((s & 1) ^ 1) L = ::max(L, max_[s ^ 1]);
93+
if (t & 1) R = ::max(R, max_[t ^ 1]);
94+
}
95+
for (ans = ::max(L, R), s >>= 1; s; s >>= 1) ans += max_[s];
96+
return ans;
97+
}
98+
99+
int operator [](int x)
100+
{
101+
return query_node(++x);
102+
}
103+
104+
private:
105+
void initialize(int x)
106+
{
107+
for (n = x + 2; __builtin_popcount(n) > 1; n += -n & n);
108+
sum_.resize(n << 1), min_.resize(n << 1), max_.resize(n << 1), add_.resize(n << 1);
109+
}
110+
111+
void build()
112+
{
113+
for (int i = n - 1; i; --i) {
114+
sum_[i] = sum_[i << 1] + sum_[i << 1 | 1];
115+
min_[i] = ::min(min_[i << 1], min_[i << 1 | 1]),
116+
min_[i << 1] -= min_[i], min_[i << 1 | 1] -= min_[i];
117+
max_[i] = ::max(max_[i << 1], max_[i << 1 | 1]),
118+
max_[i << 1] -= max_[i], max_[i << 1 | 1] -= max_[i];
119+
}
120+
}
121+
122+
int query_node(int x)
123+
{
124+
int ans = 0;
125+
for (x += n; x; x >>= 1) ans += min_[x];
126+
return ans;
127+
}
128+
129+
protected:
130+
int n;
131+
vector<int> sum_, min_, max_, add_;
132+
};

0 commit comments

Comments
 (0)