[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;
}
[NOIP 考前备战] 线段树刷题的更多相关文章
- hdu-1540线段树刷题
title: hdu-1540线段树刷题 date: 2018-10-18 19:55:21 tags: acm 刷题 categories: ACM-线段树 概述 哇,,,这道线段树的题可以说是到目 ...
- hdu-5023线段树刷题
title: hdu-5023线段树刷题 date: 2018-10-18 13:32:13 tags: acm 刷题 categories: ACM-线段树 概述 这道题和上次做的那道染色问题一样, ...
- poj-2777线段树刷题
title: poj-2777线段树刷题 date: 2018-10-16 20:01:07 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道线段树的染色问题,,, ...
- zoj-1610线段树刷题
title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...
- POJ 3468 线段树裸题
这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- 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个操作,但是顺序是乱的,现在每输入一个操作要求你输出当前的栈顶, 注意,已有操作要按它们的 ...
- hdu 1754 I Hate It 线段树基础题
Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...
- 【LOJ6062】「2017 山东一轮集训 Day2」Pair(线段树套路题)
点此看题面 大致题意: 给出一个长度为\(n\)的数列\(a\)和一个长度为\(m\)的数列\(b\),求\(a\)有多少个长度为\(m\)的子串与\(b\)匹配.数列匹配指存在一种方案使两个数列中的 ...
- hdu1823(二维线段树模板题)
hdu1823 题意 单点更新,求二维区间最值. 分析 二维线段树模板题. 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息. 一般一维线段树是切割某一可变区间直到满足所要查询 ...
随机推荐
- 关于bzoj3306(树)的一些反思
1.加零大法好,用好没烦恼 2.不要瞎开long long 3.万物皆可变成wa 4.如果超时,试图把循环中中的东西拉到外面来
- js: 获取Blob的值
this.ws.onmessage = async (msg) => { console.log('从服务端获取到了数据') // 从真正服务端发送过来的原始数据时在msg中的data字段 co ...
- Unity三维数学总结
三维向量和三角函数 三维向量 向量是指一个同时具有大小和方向,且满足平行四边形法则的几何对象. 向量的模 po点相对于世界坐标原点的距离: po.magnitude. 标准向量,归一向量,指的是将 ...
- 探索 Java 线程的创建
by emanjusaka from https://www.emanjusaka.top/archives/7 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 在并发编程中我 ...
- [HUBUCTF 2022 新生赛]ezPython
附件链接:https://wwvc.lanzouj.com/iIqq218z5x0d 给了一个pyc文件 利用命令将pyc转换为py文件 uncompyle6 ezPython.pyc > ez ...
- 使用Debian 11基础镜像制作java8镜像
下面是dockerfile内容: FROM debian:bullseye # 切换apt源为清华源,并安装vim ping telnet命令 RUN apt-get update && ...
- 【RocketMQ】事务实现原理总结
RocketMQ事务的使用场景 单体架构下的事务 在单体系统的开发过程中,假如某个场景下需要对数据库的多张表进行操作,为了保证数据的一致性,一般会使用事务,将所有的操作全部提交或者在出错的时候全部回滚 ...
- 洛谷题解 | P1051 谁拿了最多奖学金
目录 题目描述 输入格式 输出格式 输入输出样例 提示 题目思路 AC代码 题目描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1. 院士奖学金,每人 ...
- ERROR: nginx-1.22.1 installation failed.
libraries. You can either do not enable the module or install the libraries.make: *** No rule to mak ...
- 造轮子之ORM集成
Dotnet的ORM千千万,还是喜欢用EF CORE 前面一些基础完成的差不多了,接下来可以集成数据库了,官方出品的ORM还是比较香.所以接下来就是来集成EF CORE. 安装包 首先我们需要安装一下 ...