[NOIP 考前备战] 线段树刷题
备战线段树
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;
}
本文作者:PassName
本文链接:https://www.cnblogs.com/spaceswalker/p/16584078.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步