备战线段树

T1 AcWing .1275. 最大数

查询最大值 + 单点修改

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e7 + 5;

struct SegmentTree
{
int l, r;
int id;
} t[N * 4]; void push_up(int u)
{
t[u].id = max(t[u << 1].id, t[u << 1 | 1].id);
} void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (l == r)
{
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} int query(int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r)
{
return t[p].id;
}
int mid = (t[p].l + t[p].r) >> 1;
int v = 0;
if (l <= mid)
{
v = query(p << 1, l, r);
}
if (r > mid)
{
v = max(v, query(p << 1 | 1, l, r));
}
return v;
} void change(int p, int x, int v)
{
if (t[p].l == t[p].r)
{
t[p].id = v;
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid)
{
change(p << 1, x, v);
}
else
{
change(p << 1 | 1, x, v);
}
push_up(p);
} int m, p; signed main()
{
cin >> m >> p;
int n = 0;
int last = 0;
build(1, 1, m); while (m--)
{
char op;
cin >> op;
if (op == 'Q')
{
int x;
cin >> x;
last = query(1, n - x + 1, n);
cout << last << endl;
}
else
{
int x;
cin >> x;
change(1, n + 1, (last + x) % p);
n++;
}
} return 0;
}

T2 AcWing .245.你能回答这些问题吗

最大连续子段和 + 单点修改

#include <bits/stdc++.h>

#define rint register int
#define endl '\n' using namespace std; const int N = 2e6 + 5;
const int inf = 1e9; struct SegmentTree
{
int l, r;
int lmax, rmax, sum, id;
} t[N]; int n, m, a[N]; void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
t[u].lmax = max(t[u << 1].lmax, t[u << 1].sum + t[u << 1 | 1].lmax);
t[u].rmax = max(t[u << 1 | 1].rmax, t[u << 1 | 1].sum + t[u << 1].rmax);
t[u].id = max(max(t[u << 1].id, t[u << 1 | 1].id), t[u << 1].rmax + t[u << 1 | 1].lmax);
} void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (t[p].l == t[p].r)
{
t[p].id = t[p].sum = t[p].lmax = t[p].rmax = a[l];
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} void change(int p, int x, int v)
{
if (t[p].l == t[p].r)
{
t[p].id = v;
t[p].sum = v;
t[p].rmax = v;
t[p].lmax = v;
return ;
}
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid)
{
change(p << 1, x, v);
}
else
{
change(p << 1 | 1, x, v);
}
push_up(p);
} SegmentTree ask(int p, int l, int r)
{
if (l <= t[p].l && r >= t[p].r)
{
return t[p];
}
int mid = (t[p].l + t[p].r) >> 1;
SegmentTree a, b, c;
a.id = a.lmax = a.rmax = a.sum = -inf;
b.id = b.lmax = b.rmax = b.sum = -inf; c.sum = 0; if (l <= mid)
{
a = ask(p << 1, l, r);
c.sum += a.sum;
}
if (r > mid)
{
b = ask(p << 1 | 1, l, r);
c.sum += b.sum;
}
c.id = max(max(a.id, b.id), a.rmax + b.lmax);
c.lmax = max(a.lmax, b.lmax + a.sum);
if (l > mid)
{
c.lmax = max(c.lmax, b.lmax);
}
c.rmax = max(b.rmax, b.sum + a.rmax);
if (r <= mid)
{
c.rmax = max(c.rmax, a.rmax);
}
return c;
} int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
build(1, 1, n);
while (m--)
{
int op, x, y;
cin >> op >> x >> y;
if (op == 1)
{
if (x > y)
{
swap(x, y);
}
cout << ask(1, x, y).id << endl;
}
if (op == 2)
{
change(1, x, y);
}
} return 0;
}

T3 AcWing.246.区间最大公约数

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 5e6 + 5; int n, m,w[N]; struct SegmentTree
{
int l, r;
int sum, id; //id存储最大公约数
} t[N]; void push_up(SegmentTree &u, SegmentTree &l, SegmentTree &r)
{
u.sum = l.sum + r.sum;
u.id = __gcd(l.id, r.id);
} void push_up(int u)
{
push_up(t[u], t[u << 1], t[u << 1 | 1]);
} void build(int p, int l, int r)
{
if (l == r)
{
int b = w[r] - w[r - 1];
t[p] = {l, r, b, b};
}
else
{
t[p].l = l;
t[p].r = r;
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
}
} void change(int p, int x, int v)
{
if (t[p].l == x && t[p].r == x)
{
int b = t[p].sum + v;
t[p] = {x, x, b, b};
}
else
{
int mid = (t[p].l + t[p].r) >> 1;
if (x <= mid)
{
change(p << 1, x, v);
}
else
{
change(p << 1 | 1, x, v);
}
push_up(p);
}
} SegmentTree query(int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r)
{
return t[p];
}
else
{
int mid = (t[p].l + t[p].r) >> 1;
if (r <= mid)
{
return query(p << 1, l, r);
}
else if (l > mid)
{
return query(p << 1 | 1, l, r);
}
else
{
auto left = query(p << 1, l, r);
auto right = query(p << 1 | 1, l, r);
SegmentTree res;
push_up(res, left, right);
return res;
}
}
} signed main()
{
cin >> n >> m;
for (rint i = 1; i <= n; i++)
{
cin >> w[i];
}
build(1, 1, n);
int l, r;
int d;
char op;
while (m--)
{
cin >> op >> l >> r;
if (op == 'Q')
{
auto left = query(1, 1, l);
SegmentTree right({0, 0, 0, 0});
if (l + 1 <= r)
{
right = query(1, l + 1, r);
}
cout << abs(__gcd(left.sum, right.id)) << endl;
}
else
{
cin >> d;
change(1, l, d);
if (r + 1 <= n)
{
change(1, r + 1, -d);
}
}
} return 0;
}

T4 P2023 [AHOI2009]维护序列

区间修改 + 询问区间和

#include <bits/stdc++.h>

#define int long long
#define rint register int
#define endl '\n' using namespace std; const int N = 1e6 + 5; int n, m, mod, w[N]; struct SegmentTree
{
int l, r;
int add, sum, mul;
} t[N << 2]; void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
t[u].sum = t[u].sum % mod;
} void push_down(int u)
{
t[u << 1].sum = (t[u << 1].sum * t[u].mul + t[u].add * (t[u << 1].r - t[u << 1].l + 1)) % mod;
t[u<<1|1].sum = (t[u<<1|1].sum * t[u].mul + t[u].add * (t[u<<1|1].r-t[u<<1|1].l+1)) % mod;
t[u << 1].add = (t[u << 1].add * t[u].mul + t[u].add) % mod;
t[u << 1 | 1].add = (t[u << 1 | 1].add * t[u].mul + t[u].add) % mod;
t[u << 1].mul = t[u << 1].mul * t[u].mul % mod;
t[u << 1 | 1].mul = t[u << 1 | 1].mul * t[u].mul % mod;
t[u].add = 0;
t[u].mul = 1;
} void build(int p, int l, int r)
{
if (l == r)
{
t[p] = {l, r, 0, w[r], 1};
return;
}
t[p] = {l, r, 0, 0, 1};
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} void change(int p, int l, int r, int mul, int add)
{
if (t[p].l >= l && t[p].r <= r)
{
t[p].sum = (t[p].sum * mul + add * (t[p].r - t[p].l + 1)) % mod;
t[p].add = (t[p].add * mul + add) % mod;
t[p].mul = t[p].mul * mul % mod;
return;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid)
{
change(p << 1, l, r, mul, add);
}
if (r > mid)
{
change(p << 1 | 1, l, r, mul, add);
}
push_up(p);
} int query(int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r)
{
return t[p].sum;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
int res = 0;
if (l <= mid)
{
res += query(p << 1, l, r);
res = res % mod;
}
if (r > mid)
{
res += query(p << 1 | 1, l, r);
res = res % mod;
}
return res;
} signed main()
{
cin >> n >> mod;
for (rint i = 1; i <= n; i++)
{
cin >> w[i];
}
build(1, 1, n);
cin >> m;
while (m--)
{
int op, l, r, c;
cin >> op >> l >> r;
if (op == 1)
{
cin >> c;
change(1, l, r, c, 0); //*c+0
}
if (op == 2)
{
cin >> c;
change(1, l, r, 1, c); //*1+c
}
if (op == 3)
{
cout << query(1, l, r) << endl;
}
} return 0;
}

T5 P6242 【模板】线段树 3

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 1e7 + 5;
const int inf = 2e9; int n, m, op, l, r, k; struct SegmentTree
{
int sum;
int l, r, maxx, cnt, cmax, hmax;
// maxx 该区间的最大值
// cnt 该区间最大值的个数
// cmax 该区间的次大值
// hmax 该区间的历史最大值
int add1, add2, add3, add4;
// add1 该区间最大值的懒标。
// add2 该区间非最大值的懒标记
// add3 该区间最大值的懒标记的最大值
// add4 该区间非最大的值的懒标记的最大值
} t[N]; inline int read()
{
int x = 0, falg = 0;
char c = getchar();
while (c > '9' || c < '0')
{
if (c == '-')
falg = 1;
c = getchar();
}
while (c <= '9' && c >= '0')
{
x = x * 10 + c - '0';
c = getchar();
}
return falg ? -x : x;
} void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
t[u].maxx = max(t[u << 1].maxx, t[u << 1 | 1].maxx);
t[u].hmax = max(t[u << 1].hmax, t[u << 1 | 1].hmax); if (t[u << 1].maxx == t[u << 1 | 1].maxx)
{
t[u].cmax = max(t[u << 1].cmax, t[u << 1 | 1].cmax);
t[u].cnt = t[u << 1].cnt + t[u << 1 | 1].cnt;
} else if (t[u << 1].maxx > t[u << 1 | 1].maxx)
{
t[u].cmax = max(t[u << 1].cmax, t[u << 1 | 1].maxx);
t[u].cnt = t[u << 1].cnt;
} else
{
t[u].cmax = max(t[u << 1].maxx, t[u << 1 | 1].cmax);
t[u].cnt = t[u << 1 | 1].cnt;
}
} void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (l == r)
{
t[p].sum = t[p].maxx = t[p].hmax = read();
t[p].cnt = 1;
t[p].cmax = -inf;
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} void change(int p, int k1, int k2, int k3, int k4)
{
// k1 区间最大值要加的数
// k2 区间非最大值要加的的数
// k3 区间最大值要加上的数的最大值
// k4 区间非最大值要加上的数的最大值
t[p].sum += k1 * t[p].cnt + k2 * (t[p].r - t[p].l + 1 - t[p].cnt);
t[p].hmax = max(t[p].hmax, t[p].maxx + k3);
t[p].add3 = max(t[p].add3, t[p].add1 + k3);
t[p].add4 = max(t[p].add4, t[p].add2 + k4);
t[p].maxx += k1;
t[p].add1 += k1;
t[p].add2 += k2;
if (t[p].cmax != -inf)
{
t[p].cmax += k2;
}
} void push_down(int u)
{
int maxn = max(t[u << 1].maxx, t[u << 1 | 1].maxx); if (t[u << 1].maxx == maxn)
{
change(u << 1, t[u].add1, t[u].add2, t[u].add3, t[u].add4);
}
else
{
change(u << 1, t[u].add2, t[u].add2, t[u].add4, t[u].add4);
} if (t[u << 1 | 1].maxx == maxn)
{
change(u << 1 | 1, t[u].add1, t[u].add2, t[u].add3, t[u].add4);
}
else
{
change(u << 1 | 1, t[u].add2, t[u].add2, t[u].add4, t[u].add4);
} t[u].add1 = t[u].add2 = t[u].add3 = t[u].add4 = 0;
} void update_add(int p, int l, int r, int k)
{
if (l > t[p].r || t[p].l > r)
{
return;
}
if (l <= t[p].l && t[p].r <= r)
{
change(p, k, k, k, k);
return;
}
push_down(p);
update_add(p << 1, l, r, k);
update_add(p << 1 | 1, l, r, k);
push_up(p);
} void update_min(int p, int l, int r, int k)
{
if (l > t[p].r || t[p].l > r || k >= t[p].maxx)
{
return;
}
if (l <= t[p].l && t[p].r <= r && k > t[p].cmax)
{
change(p, k - t[p].maxx, 0, k - t[p].maxx, 0);
return;
}
push_down(p);
update_min(p << 1, l, r, k);
update_min(p << 1 | 1, l, r, k);
push_up(p);
} int query_sum(int p, int l, int r)
{
if (l > t[p].r || t[p].l > r)
{
return 0;
}
if (l <= t[p].l && t[p].r <= r)
{
return t[p].sum;
}
push_down(p);
return query_sum(p << 1, l, r) + query_sum(p << 1 | 1, l, r);
} int query_maxx(int p, int l, int r)
{
if (l > t[p].r || t[p].l > r)
{
return -inf;
}
if (l <= t[p].l && t[p].r <= r)
{
return t[p].maxx;
}
push_down(p);
return max(query_maxx(p << 1, l, r), query_maxx(p << 1 | 1, l, r));
} int query_hmax(int p, int l, int r)
{
if (l > t[p].r || t[p].l > r)
{
return -inf;
}
if (l <= t[p].l && t[p].r <= r)
{
return t[p].hmax;
}
push_down(p);
return max(query_hmax(p << 1, l, r), query_hmax(p << 1 | 1, l, r));
} signed main()
{
n = read();
m = read();
build(1, 1, n);
while (m--)
{
op = read();
l = read();
r = read(); if (op == 1)
{
k = read();
update_add(1, l, r, k);
} if (op == 2)
{
k = read();
update_min(1, l, r, k);
} if (op == 3)
{
cout << query_sum(1, l, r) << endl;
} if (op == 4)
{
cout << query_maxx(1, l, r) << endl;
} if (op == 5)
{
cout << query_hmax(1, l, r) << endl;
}
} return 0;
}

T6 P4145 花神游历各国

区间开方 + 区间查询

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 4e5 + 5; struct SegmentTree
{
int sum;
bool tag; //表示这个节点对应的区间内的数是否都是 0 或 1。
//一个点如果是1或者0,那么这个点的开根是没有意义的
//而即使是一个1e9,在经过不到10次开根后也会变成1
//要是这个点是1或者0,那么tag就等于1
//在维护的时候,只要左右子节点的tag都等于1时,这个点的tag就等于1
} t[N]; int w[N], n, m; void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
if (t[u << 1].tag && t[u << 1 | 1].tag)
{
t[u].tag = 1;
}
else
{
t[u].tag = 0;
}
} void build(int u, int l, int r)
{
if (l == r)
{
t[u].sum = w[l];
if (w[l] == 0 || w[l] == 1)
{
t[u].tag = 1;
}
else
{
t[u].tag = 0;
}
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
push_up(u);
} void change(int u, int l, int r, int x, int v)
{
if (l == r)
{
t[u].sum = sqrt(t[u].sum);
if (t[u].sum == 0 || t[u].sum == 1)
{
t[u].tag = 1;
}
return;
}
int mid = (l + r) >> 1;
if (x <= mid && !t[u << 1].tag)
{
change(u << 1, l, mid, x, v);
}
if (v > mid && !t[u << 1 | 1].tag)
{
change(u << 1 | 1, mid + 1, r, x, v);
}
push_up(u);
} int query(int u, int l, int r, int x, int v)
{
if (x <= l && v >= r)
{
return t[u].sum;
}
int mid = (l + r) >> 1;
int res = 0;
if (x <= mid)
{
res += query(u << 1, l, mid, x, v);
}
if (v > mid)
{
res += query(u << 1 | 1, mid + 1, r, x, v);
}
return res;
} inline int read()
{
int x = 0;
bool f = 0;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = 1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = (x << 3) + (x << 1) + c - 48;
c = getchar();
}
return f ? -x : x;
} signed main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
cin >> n;
for (rint i = 1; i <= n; i++)
{
w[i] = read();
}
build(1, 1, n);
m = read();
while (m--)
{
int op = read(), l = read(), r = read();
if (l > r)
{
swap(l, r);
}
if (op == 0)
{
change(1, 1, n, l, r);
}
if (op == 1)
{
cout << query(1, 1, n, l, r) << endl;
}
}
return 0;
}

T7 CF240F TorCoder

回文字符串问题 多棵线段树


#define rint register int
#define endl '\n' using namespace std; const int N = 1e5 + 5; int n, q, ans[26 + 4];
char s[N]; struct SegmentTree
{
int l, r;
int sum[26 + 4];
int add;
// sum 为节点上每个字母的数量 add 为 lazy 标记
//如果父区间存 2 个 a , lazy 即为 a , 需要时下放
} t[N << 2]; void clear(int u)
{
for (rint i = 1; i <= 26; i++)
{
t[u].sum[i] = 0;
}
} void push_up(int u)
{
for (rint i = 1; i <= 26; i++)
{
t[u].sum[i] = t[u << 1].sum[i] + t[u << 1 | 1].sum[i];
}
} void push_down(int u)
{
if (t[u].add)
{
t[u << 1].add = t[u].add;
t[u << 1 | 1].add = t[u].add;
clear(u << 1);
clear(u << 1 | 1);
t[u << 1].sum[t[u].add] = t[u << 1].r - t[u << 1].l + 1;
t[u << 1 | 1].sum[t[u].add] = t[u << 1 | 1].r - t[u << 1 | 1].l + 1;
t[u].add = 0;
}
} void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (l == r)
{
t[p].sum[s[l] - 'a' + 1] = 1;
t[p].add = s[l] - 'a' + 1;
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} void query(int p, int l, int r)
{
if (t[p].l == l && r == t[p].r)
{
for (int i = 1; i <= 26; i++)
{
ans[i] += t[p].sum[i];
}
return;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (r <= mid)
{
query(p << 1, l, r);
}
else if (l > mid)
{
query(p << 1 | 1, l, r);
}
else
{
query(p << 1, l, mid);
query(p << 1 | 1, mid + 1, r);
}
push_up(p);
} void update(int p, int l, int r, int x)
{
if (t[p].l == l && r == t[p].r)
{
clear(p);
t[p].add = x;
t[p].sum[x] = t[p].r - t[p].l + 1;
return;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (r <= mid)
{
update(p << 1, l, r, x);
}
else if (l > mid)
{
update(p << 1 | 1, l, r, x);
}
else
{
update(p << 1, l, mid, x);
update(p << 1 | 1, mid + 1, r, x);
}
push_up(p);
} void change(int l, int r)
{
memset(ans, 0 ,sizeof ans);
query(1, l, r);
int sum = 0;
for (rint i = 1; i <= 26; i++)
{
if (ans[i] & 1)
{
sum++;
}
if (sum > 1)
{
return ;
}
}
for (rint i = 1; i <= 26; i++)
{
if (ans[i])
{
if (ans[i] / 2)
{
update(1, l, l + ans[i] / 2 - 1, i);
update(1, r - ans[i] / 2 + 1, r, i);
l += ans[i] / 2;
r -= ans[i] / 2;
}
if (ans[i] % 2)
{
int mid = (l + r) >> 1;
update(1, mid, mid, i);
}
}
}
} void query_print(int p, int l, int r)
{
if (t[p].add)
{
for (int i = 1; i <= t[p].r - t[p].l + 1; i++)
{
putchar(t[p].add - 1 + 'a');
}
return;
}
int mid = (l + r) >> 1;
query_print(p << 1, l, mid);
query_print(p << 1 | 1, mid + 1, r);
} int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
cin >> n >> q >> s + 1;
build(1, 1, n);
int l, r; while (q--)
{
int l ,r;
cin >> l >> r;
change(l, r);
} query_print(1, 1, n); return 0;
}

T8 P3924 康娜的线段树

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 1e6 + 5; int n, m, qwq;
int max_deep, res, ans;
int a[N], dep[N], sum[N]; struct SegmentTree
{
int l, r;
int sum, add;
} t[N << 2]; void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
} void build(int p, int l, int r, int d)
{
t[p].l = l;
t[p].r = r;
if (l == r)
{
t[p].sum = a[l];
dep[l] = d;
max_deep = max(max_deep, dep[l]);
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid, d + 1);
build(p << 1 | 1, mid + 1, r, d + 1);
push_up(p);
} int query(int p, int l, int r, int d, int sum)
{
if (l == r)
{
return (1 << d) * (sum + t[p].sum);
}
else
{
int mid = (l + r) >> 1;
return query(p << 1, l, mid, d - 1, sum + t[p].sum) + query(p << 1 | 1, mid + 1, r, d - 1, sum + t[p].sum);
}
} signed main()
{
ios::sync_with_stdio (false) ;
cin.tie(0);
cout.tie(0); cin >> n >> m >> qwq; for (rint i = 1; i <= n; i++)
{
cin >> a[i];
} build(1, 1, n, 1);
ans = query(1, 1, n, max_deep - 1, 0);
res = 1 << (max_deep - 1);
int g = __gcd(qwq, res); res /= g;
qwq /= g; for (rint i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] + (((1 << dep[i]) - 1) << (max_deep - dep[i]));
} for (rint i = 1; i <= m; i++)
{
int l, r, x;
cin >> l >> r >> x;
ans += (sum[r] - sum[l - 1]) * x;
cout << (ans / res * qwq) << endl;
} return 0;
}

T9 CF444C DZY Loves Colors

#include <bits/stdc++.h>

#define rint register int
#define endl '\n'
#define int long long using namespace std; const int N = 1e5 + 5; int n, m; struct SegmentTree
{
int lazy;
int ans, len;
int val;
} t[N << 2]; void push_up(int u)
{
t[u].ans = t[u << 1].ans + t[u << 1 | 1].ans;
} void push_down(int u, int l, int r)
{
t[u << 1].lazy += t[u].lazy;
t[u << 1 | 1].lazy += t[u].lazy;
t[u << 1].ans += t[u].lazy * t[u << 1].len;
t[u << 1 | 1].ans += t[u].lazy * t[u << 1 | 1].len;
t[u << 1].val = t[u << 1 | 1].val = t[u].val;
t[u].lazy = 0;
t[u].val = 0;
} void build(int p, int l, int r)
{
t[p].len = r - l + 1;
t[p].ans = t[p].lazy = t[p].val = 0;
if (l == r)
{
t[p].val = l;
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
} void change(int p, int l, int r, int L, int R, int x)
{
if (L <= l && r <= R && t[p].val)
{
t[p].lazy += abs(t[p].val - x);
t[p].ans += abs(t[p].val - x) * t[p].len;
t[p].val = x;
return;
}
if (t[p].val)
{
push_down(p, l, r);
}
int mid = (l + r) >> 1;
if (L <= mid)
{
change(p << 1, l, mid, L, R, x);
}
if (R > mid)
{
change(p << 1 | 1, mid + 1, r, L, R, x);
}
t[p].val = t[p << 1].val == t[p << 1 | 1].val ? t[p << 1].val : 0;
push_up(p);
} int query(int p, int l, int r, int L, int R)
{
if (L <= l && r <= R)
{
return t[p].ans;
}
if (t[p].val)
{
push_down(p, l, r);
}
int mid = (l + r) >> 1;
int res = 0;
if (L <= mid)
{
res += query(p << 1, l, mid, L, R);
}
if (R > mid)
{
res += query(p << 1 | 1, mid + 1, r, L, R);
} return res;
} signed main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout); cin >> n >> m; build(1, 1, n); while (m--)
{
int op, l, r, x;
cin >> op;
if (op == 1)
{
cin >> l >> r >> x;
change(1, 1, n, l, r, x);
}
if (op == 2)
{
cin >> l >> r;
cout << query(1, 1, n, l, r) << endl;
}
} return 0;
}

T10 CF1696D Permutation Graph

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int mod = 5;
const int N = 2e6 + 10;
const int inf = 0x3f3f3f3f; int n, m, ans, l, r, a[N], pos[N]; struct SegmentTree
{
int l, r;
int minn, maxn;
} t[N]; void push_up(int u)
{
t[u].minn = min(t[u << 1].minn, t[u << 1 | 1].minn);
t[u].maxn = max(t[u << 1].maxn, t[u << 1 | 1].maxn);
} void build(int p, int l, int r)
{
t[p] = {l, r}; if (l == r)
{
t[p] = {l, r, a[l], a[r]};
return;
} int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} int query_max(int u, int l, int r)
{
if (t[u].l >= l && t[u].r <= r)
{
return t[u].maxn;
}
int mid = (t[u].l + t[u].r) >> 1;
int maxn = -inf; if (l <= mid)
{
maxn = max(maxn, query_max(u << 1, l, r));
}
if (r > mid)
{
maxn = max(maxn, query_max(u << 1 | 1, l, r));
} push_up(u); return maxn;
} int query_min(int u, int l, int r)
{
if (t[u].l >= l && t[u].r <= r)
{
return t[u].minn;
} int mid = (t[u].l + t[u].r) >> 1;
int minn = inf; if (l <= mid)
{
minn = min(minn, query_min(u << 1, l, r));
}
if (r > mid)
{
minn = min(minn, query_min(u << 1 | 1, l, r));
} push_up(u); return minn;
} int dfs(int l, int r)
{
if (l + 1 == r)
{
return 1;
}
if (l >= r)
{
return 0;
} int maxn = query_max(1, l, r);
int minn = query_min(1, l, r); int L = pos[maxn], R = pos[minn]; if (L > R)
{
swap(L, R);
} return dfs(l, L) + 1 + dfs(R, r);
} signed main()
{
int T;
cin >> T; while(T--)
{
cin >> n;
for (rint i = 1; i <= n; i++)
{
cin >> a[i];
pos[a[i]] = i;
}
build(1, 1, n);
if (n == 1)
{
cout << 0 << endl;
continue;
}
cout << dfs(1, n) << endl;
} return 0;
}

T11 P3602 Koishi Loves Segments

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 4e6 + 5; struct SegmentTree
{
int l, r;
int minn, lazy;
} t[N]; bool cmp(SegmentTree x, SegmentTree y)
{
if (x.r == y.r)
{
return x.l > y.l;
} return x.r < y.r;
} int stk1[N], top1, stk2[N], top2;
int s[N], num;
int a[N], n, m; int inline max(int a, int b)
{
return a > b ? a : b;
} void push_up(int u)
{
t[u].minn = min(t[u << 1].minn, t[u << 1 | 1].minn);
} void build(int u, int l, int r)
{
if (l == r)
{
t[u].minn = a[l];
return;
} int mid = l + r >> 1; build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
push_up(u);
} void add(int u, int v)
{
t[u].minn += v;
t[u].lazy += v;
} void pushdown(int u, int v)
{
if (!t[u].lazy)
{
return;
} add(u << 1, t[u].lazy);
add(u << 1 | 1, t[u].lazy);
t[u].lazy = 0;
} int query(int u, int l, int r, int x, int y)
{
if (l > y || r < x)
{
return 0x3f3f3f3f;
}
if (l >= x && r <= y)
{
return t[u].minn;
} pushdown(u, t[u].lazy); int mid = l + r >> 1;
int ans = 0x3f3f3f3f; if (x <= mid)
{
ans = min(ans, query(u << 1, l, mid, x, y));
}
if (y > mid)
{
ans = min(ans, query(u << 1 | 1, mid + 1, r, x, y));
} return ans;
} void change(int u, int l, int r, int x, int y, int v)
{
if (l > y || r < x)
return;
if (l >= x && r <= y)
{
add(u, v);
return;
} pushdown(u, t[u].lazy);
int mid = l + r >> 1; if (x <= mid)
{
change(u << 1, l, mid, x, y, v);
}
if (y > mid)
{
change(u << 1 | 1, mid + 1, r, x, y, v);
}
push_up(u);
} signed main()
{
cin >> n >> m; for (rint i = 1; i <= n; i++)
{
cin >> t[i].l >> t[i].r;
s[++num] = t[i].l;
s[++num] = t[i].r;
} for (rint i = 1; i <= m; i++)
{
cin >> stk1[++top1] >> stk2[++top2];
s[++num] = stk1[top1];
} sort(s + 1, s + num + 1);
int maxn = unique(s + 1, s + num + 1) - s - 1; for (rint i = 1; i <= n; i++)
{
t[i].l = lower_bound(s + 1, s + maxn + 1, t[i].l) - s;
t[i].r = lower_bound(s + 1, s + maxn + 1, t[i].r) - s;
} memset(a, 0x3f, sizeof a); for (rint i = 1; i <= m; i++)
{
int x = lower_bound(s + 1, s + maxn + 1, stk1[i]) - s;
a[x] = min(a[x], max(stk2[i], 0));
} sort(t + 1, t + n + 1, cmp);
build(1, 1, maxn);
int ans = 0; for (rint i = 1; i <= n; i++)
{
if (query(1, 1, maxn, t[i].l, t[i].r) > 0)
{
ans++;
change(1, 1, maxn, t[i].l, t[i].r, -1);
}
} cout << ans << endl; return 0;
}

T12 P4513 小白逛公园

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n' using namespace std; const int N = 5e6 + 5;
const int inf = 0x3f3f3f3f; int a[N], n, m; struct SegmentTree
{
int lx, sum, rx;
int ans;
int l, r;
//lx 左边界以左的最大子段和
//rx 右边界以右的最大子段和
//ans 最后的最大子段和
//sum 区间总和
} t[N]; void push_up(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
t[u].lx = max(t[u << 1].lx, t[u << 1].sum + t[u << 1 | 1].lx);
t[u].rx = max(t[u << 1 | 1].rx, t[u << 1 | 1].sum + t[u << 1].rx);
t[u].ans = max(max(t[u << 1].ans, t[u << 1 | 1].ans), t[u << 1].rx + t[u << 1 | 1].lx);
} void build(int p, int l, int r)
{
t[p].l = l;
t[p].r = r;
if (l == r)
{
t[p].sum = t[p].lx = t[p].rx = t[p].ans = a[l];
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
} void change(int p, int l, int r, int x, int v)
{
if (x < l || x > r)
{
return;
}
if (l == x && r == x)
{
t[p].ans = t[p].lx = t[p].rx = t[p].sum = v;
return;
}
int mid = l + ((r - l) >> 1);
change(p << 1, l, mid, x, v);
change(p << 1 | 1, mid + 1, r, x, v);
push_up(p);
} SegmentTree query(int p, int l, int r)
{
if (l <= t[p].l && r >= t[p].r)
{
return t[p];
}
SegmentTree a, b, ans;
a.lx = a.rx = a.ans = -inf;
b.lx = b.rx = b.ans = -inf;
a.sum = b.sum = 0;
ans.ans = -inf;
ans.sum = 0;
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid)
{
a = query(p << 1, l, r);
ans.sum += a.sum;
}
if (r >= mid + 1)
{
b = query(p << 1 | 1, l, r);
ans.sum += b.sum;
}
ans.ans = max(a.rx + b.lx, max(a.ans, b.ans));
ans.lx = max(a.lx, a.sum + b.lx);
ans.rx = max(b.rx, b.sum + a.rx);
if (l > mid)
{
ans.lx = max(ans.lx, b.lx);
}
if (r < mid)
{
ans.rx = max(ans.rx, a.rx);
}
return ans;
} signed main()
{
cin >> n >> m;
for (rint i = 1; i <= n; i++)
{
cin >> a[i];
}
build(1, 1, n);
while (m--)
{
int op, l, r;
cin >> op >> l >> r;
if (op == 1)
{
if (l > r)
{
swap(l, r);
}
cout << query(1, l, r).ans << endl;
}
if (op == 2)
{
change(1, 1, n, l, r);
}
} return 0;
}

[NOIP 考前备战] 线段树刷题的更多相关文章

  1. hdu-1540线段树刷题

    title: hdu-1540线段树刷题 date: 2018-10-18 19:55:21 tags: acm 刷题 categories: ACM-线段树 概述 哇,,,这道线段树的题可以说是到目 ...

  2. hdu-5023线段树刷题

    title: hdu-5023线段树刷题 date: 2018-10-18 13:32:13 tags: acm 刷题 categories: ACM-线段树 概述 这道题和上次做的那道染色问题一样, ...

  3. poj-2777线段树刷题

    title: poj-2777线段树刷题 date: 2018-10-16 20:01:07 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道线段树的染色问题,,, ...

  4. zoj-1610线段树刷题

    title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...

  5. POJ 3468 线段树裸题

    这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...

  6. [AHOI 2009] 维护序列(线段树模板题)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...

  7. Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 线段树好题

    http://codeforces.com/contest/760/problem/E 题目大意:现在对栈有m个操作,但是顺序是乱的,现在每输入一个操作要求你输出当前的栈顶, 注意,已有操作要按它们的 ...

  8. hdu 1754 I Hate It 线段树基础题

    Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...

  9. 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)

    点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...

  10. hdu1823(二维线段树模板题)

    hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...

随机推荐

  1. ValueError: Max value is 14 解决方案

    方案一(有时会失效): 将EXCEL文件中的格式全部清除即可.最好是复制,然后只粘贴值. 方案二(指定引擎): data = pd.read_excel(path, engine="open ...

  2. Python类与面向对象

    Python类与面向对象 一.面向对象 1.1 面向对象概述 面向对象与面向过程? 面向过程编程的基本思想是:分析解决问题的步骤,使用函数实现每步对应的功能,按照步骤的先后顺序依次调用函数.面向过程只 ...

  3. spring-mvc系列:简介和基本使用

    目录 一.简介 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.基本使用 1.开发环境 2.创建maven工程 3.配置web.xml 4.创建SpringMVC的配 ...

  4. 牛客小白月赛65 D题 题解

    原题链接 题意描述 一共有两堆石子,第一堆有 \(a\) 个,第二堆有 \(b\) 个,牛牛和牛妹轮流取石子,牛牛先手,每次取石子的时候只能从以下 \(2\) 种方案种挑一种来取(对于选择的方案数必须 ...

  5. Go/C++/Java中的数组对比

    数组是大多数编程语言中的基本数据结构.然而,不同的编程语言对数组的实现和语义有所不同.以下是 Go.C++ 和 Java 中数组的主要区别: 1. 基本性质 Go: 数组是值类型.赋值或将数组传递给函 ...

  6. cs50ai1

    cs50ai1-------Knowledge cs50ai1-------Knowledge 基础知识 课后题目 代码实践 学习链接 总结 基础知识 对我们来说,一些基本的logic是自然而然的,我 ...

  7. Python 潮流周刊#17:Excel 终于支持 Python 了、Meta 重磅开源新项目、Mojo 新得 1 亿美元融资

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中两则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...

  8. C与CPP常见编译工具链与构建系统简介

    笔者最近在研究CEF的CMake工程,心血来潮想要对各种编译工具链以及构建系统做一个简单的总结,于是就有了本文.本文不会讲解任何关于C/C++语言方面的内容,主要C/C++的编译出发,介绍各种编译工具 ...

  9. burpsuite验证码爆破后台夺权

    目录 准备工作 爆破 同时爆破用户名密码和验证码 筛查爆破结果的成功输出 创建新用户远程桌面连接 准备工作 安装python 安装muggle_ocr库 运行xp_CAPTCHA服务端 burpsui ...

  10. 实训——基于大数据Hadoop平台的医疗平台项目实战

    文章目录 医疗平台项目描述 数据每列的含义 数据分析业务需求 架构图 成果图 环境搭建 非常感谢各位的认可,最近太多人找我问东问西,故在此进行说明一下: 首先这个是在Linux上基于Hadoop的搭建 ...