线段树代码
易错点:
1、<< 与 >> 不要写反
2、左右区间分别是[l, m] 和 [m + 1, r] m后面的+1不要忘记
3、pushdown 不要忘记删除父节点的标记
4、节点信息个数与赋值时的个数要匹配
5、想好要不要加 &
6、建树时除了叶节点,其他节点不要忘记赋值!
单点修改,单点查询
区间最后L个最大数
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, m, x, last, mod;
struct node
{
int l, r;
int v;
}t[N * 4];
void build(int u, int l, int r)
{
t[u] = {l, r};
if (l == r) return;
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
}
void pushup(int u)
{
t[u].v = max(t[u << 1].v, t[u << 1 | 1].v);
}
int quire(int u, int l, int r)
{
if(t[u].l >= l && t[u].r <= r) return t[u].v;
int m = t[u].l + t[u].r >> 1;
int v = 0;
if(l <= m) v = quire(u << 1, l, r);
if(r > m) v = max(v, quire(u << 1 | 1, l, r));
return v;
}
void modify(int u, int x, int v)
{
if (t[u].l == x && t[u].r == x)
{
t[u].v = v;
return;
}
int m = t[u].l + t[u].r >> 1;
if(x <= m) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
int main()
{
cin >> m >> mod;
build(1, 1, m);
while (m --)
{
char op[3];
cin >> op;
if (op[0] == 'Q')
{
int L;
cin >> L;
last = quire(1, n - L + 1, n);
cout << last << "\n";
}
else
{
int x;
cin >> x;
modify(1, ++n, ((long long)x + last) % mod);
}
}
return 0;
}
区间最大连续子段和
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 0x7fffffff;
const int N = 5e5 + 5;
int n, m;
int a[N];
struct node
{
int l, r;
int mx, lmx, rmx, sum;
}t[N * 4];
void pushup(node &u, node &l, node &r)
{
u.sum = l.sum + r.sum;
u.lmx = max(l.lmx, l.sum + r.lmx);
u.rmx = max(r.rmx, r.sum + l.rmx);
u.mx = max({r.mx, l.mx, l.rmx + r.lmx});
}
void pushup(int u)
{
pushup(t[u], t[u << 1], t[u << 1 | 1]);
}
void build(int u, int l, int r)
{
if(l == r) t[u] = {l, r, a[l], a[l], a[l], a[l]};
else
{
t[u] = {l, r};
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
pushup(u);
}
}
void modify(int u, int x, int v)
{
if(t[u].l == x && t[u].r == x) t[u] = {x, x, v, v, v, v};
else
{
int m = t[u].l + t[u].r >> 1;
if(x <= m) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}
node quire(int u, int l, int r)
{
if(t[u].l >= l && t[u].r <= r) return t[u];
int m = t[u].l + t[u].r >> 1;
if(r <= m) return quire(u << 1, l, r);
else if(l > m) return quire(u << 1 | 1, l, r);
else
{
auto left = quire(u << 1, l, r);
auto right = quire(u << 1 | 1, l, r);
node res;
pushup(res, left, right);
return res;
}
}
int main ()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
build(1, 1, n);
while (m --)
{
int k, x, y;
cin >> k >> x >> y;
if(k == 1)
{
if(x > y) swap(x, y);
cout << quire(1, x, y).mx << "\n";
}
else modify(1, x, y);
}
return 0;
}
/*
*/
区间最大公约数
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 0x7fffffff;
const int N = 5e5 + 5;
ll n, a[N], m;
struct node
{
int l, r;
ll sum, gcdd;
}t[N * 4];
void pushup(node &u, node &l, node &r)
{
u.sum = l.sum + r.sum;
u.gcdd = __gcd(l.gcdd, r.gcdd);
}
void pushup(int u)
{
pushup(t[u], t[u << 1], t[u << 1 | 1]);
}
void build(int u, int l, int r)
{
if (l == r) t[u] = {l, l, a[l], a[l]};
else
{
t[u] = {l, r};
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
pushup(u);
}
}
void modify(int u, int x, ll v)
{
if (t[u].l == x && t[u].r == x) t[u] = {x, x, t[u].sum + v, t[u].sum + v};
else
{
int m = t[u].l + t[u].r >> 1;
if (x <= m) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}
node quire(int u, int l, int r)
{
if (t[u].l >= l && t[u].r <= r) return t[u];
int m = t[u].l + t[u].r >> 1;
if (r <= m) return quire(u << 1, l, r);
else if (l > m) return quire(u << 1 | 1, l, r);
else
{
auto left = quire(u << 1, l, r);
auto right = quire(u << 1 | 1, l, r);
node res;
pushup(res, left, right);
return res;
}
}
int main ()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = n; i; i --) a[i] -= a[i - 1];
build(1, 1, n);
while (m --)
{
char op[3];
int l, r;
cin >> op >> l >> r;
if (op[0] == 'C')
{
ll d;
cin >> d;
modify(1, l, d);
if (r + 1 <= n) modify(1, r + 1, -d);
}
else
{
auto x = l < r ? quire(1, l + 1, r).gcdd : 0ll;
auto y = quire(1, 1, l).sum;
cout << abs(__gcd(x, y)) << "\n";
}
}
return 0;
}
/*
*/
区间修改,区间查询
涉及懒标记
区间加,查询区间和
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 0x7fffffff;
const int N = 1e5 + 5;
int n, m;
ll a[N];
struct node
{
int l, r;
ll add, sum;
}t[N * 4];
void pushdown(int u)
{
auto &root = t[u], &left = t[u << 1], &right = t[u << 1 | 1];
if (root.add)
{
left.add += root.add, left.sum += (ll)(left.r - left.l + 1) * root.add;
right.add += root.add, right.sum += (ll)(right.r - right.l + 1) * root.add;
root.add = 0;
}
}
void pushup(int u)
{
t[u].sum = t[u << 1].sum + t[u << 1 | 1].sum;
}
void build(int u, int l, int r)
{
if (l == r) t[u] = {l, l, 0, a[l]};
else
{
t[u] = {l, r};
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, ll d)
{
if (t[u].l >= l && t[u].r <= r)
{
t[u].add += d;
t[u].sum += (ll)(t[u].r - t[u].l + 1) * d;
}
else
{
pushdown(u);
int m = t[u].l + t[u].r >> 1;
if (l <= m) modify(u << 1, l, r, d);
if (r > m) modify(u << 1 | 1, l, r, d);
pushup(u);
}
}
ll quire(int u, int l, int r)
{
if (t[u].l >= l && t[u].r <= r) return t[u].sum;
pushdown(u);
int m = t[u].l + t[u].r >> 1;
ll res = 0;
if(l <= m) res = quire(u << 1, l, r);
if(r > m) res += quire(u << 1 | 1, l, r);
return res;
}
int main ()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
build(1, 1, n);
while(m --)
{
char op[3];
int l, r;
cin >> op >> l >> r;
if (op[0] == 'C')
{
ll d;
cin >> d;
modify(1, l, r, d);
}
else
{
cout << quire(1, l, r) << "\n";
}
}
return 0;
}
/*
*/
区间加乘,查询区间和
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 0x7fffffff;
const int N = 1e5 + 5;
struct node
{
int l, r, add, mul, sum;
}t[N * 4];
int n, mod;
int a[N];
void eval(int u, int add, int mul)
{
t[u].sum = ((ll)t[u].sum * mul + (ll)add * (t[u].r - t[u].l + 1)) % mod;
t[u].mul = (ll)t[u].mul * mul % mod;
t[u].add = ((ll)t[u].add * mul + add) % mod;
}
void pushup(int u)
{
t[u].sum = (t[u << 1].sum + t[u << 1 | 1].sum) % mod;
}
void pushdown(int u)
{
eval(u << 1, t[u].add, t[u].mul), eval(u << 1 | 1, t[u].add, t[u].mul);
t[u].add = 0, t[u].mul = 1;
}
void build(int u, int l, int r)
{
if (l == r) t[u] = {l, l, 0, 1, a[l]};
else
{
t[u] = {l, r, 0, 1, 0};
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int add, int mul)
{
if (t[u].l >= l && t[u].r <= r) eval(u, add, mul);
else
{
pushdown(u);
int m = t[u].l + t[u].r >> 1;
if(l <= m) modify(u << 1, l, r, add, mul);
if(r > m) modify(u << 1 | 1, l, r, add, mul);
pushup(u);
}
}
int quire(int u, int l, int r)
{
if(t[u].l >= l && t[u].r <= r) return t[u].sum;
else
{
pushdown(u);
int m = t[u].l + t[u].r >> 1;
int res = 0;
if(l <= m) res = quire(u << 1, l, r);
if(r > m) res = ((ll) res + quire(u << 1 | 1, l, r)) % mod;
return res;
}
}
int main ()
{
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> mod;
for (int i = 1; i <= n; i ++) cin >> a[i];
build(1, 1, n);
int m; cin >> m;
while (m --)
{
int k, l, r; cin >> k >> l >> r;
if (k == 3)
{
cout << quire(1, l, r) % mod << "\n";
}
else
{
int c; cin >> c;
if (k == 1) modify(1, l, r, 0, c);
else modify(1, l, r, c, 1);
}
}
return 0;
}
/*
*/
扫描线+二分+离散化(在y轴上建立线段树,线段树维护的节点代表一段区间)
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 0x7fffffff;
const int N = 1E4 + 5;
int n;
struct seg
{
double x, y1, y2;
int k;
bool operator < (const seg &w) &
{
return x < w.x;
}
}seg[2 * N];
struct node
{
int l, r;
double len;
int cnt;
}t[8 * N];
vector<double> ys;
int find(double x) {return lower_bound(ys.begin(), ys.end(), x) - ys.begin();}
void pushup(int u)
{
if (t[u].cnt) t[u].len = ys[t[u].r + 1] - ys[t[u].l];
else if (t[u].l == t[u].r) t[u].len = 0;
else t[u].len = t[u << 1].len + t[u << 1 | 1].len;
}
void build(int u, int l, int r)
{
t[u] = {l, r, 0, 0};
if (l != r)
{
int m = l + r >> 1;
build(u << 1, l, m), build(u << 1 | 1, m + 1, r);
}
}
void modify(int u, int l, int r, int k)
{
if (t[u].l >= l && t[u].r <= r)
{
t[u].cnt += k;
pushup(u);
}
else
{
int m = t[u].l + t[u].r >> 1;
if (l <= m) modify(u << 1, l, r, k);
if(r > m) modify(u << 1 | 1, l, r, k);
pushup(u);
}
}
int main ()
{
ios::sync_with_stdio(0); cin.tie(0);
int tt = 0;
while (cin >> n, n)
{
ys.clear();
for (int i = 0, j = 0; i < n; i ++)
{
double x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
seg[j ++] = {x1, y1, y2, 1};
seg[j ++] = {x2, y1, y2, -1};
ys.push_back(y1), ys.push_back(y2);
}
sort(ys.begin(), ys.end());
ys.erase(unique(ys.begin(), ys.end()), ys.end());
sort(seg, seg + 2 * n);
build(1, 0, ys.size() - 2);
double res = 0 ;
for (int i = 0; i < 2 * n; i ++)
{
if (i) res += (seg[i].x - seg[i - 1].x) * t[1].len;
int l = find(seg[i].y1), r = find(seg[i].y2) - 1;
modify(1, l, r, seg[i].k);
}
cout << fixed << setprecision(2) << "Test case #" << ++ tt << "\n";
cout << "Total explored area: " << res << "\n\n";
}
return 0;
}
/*
*/

浙公网安备 33010602011771号