线段树代码

易错点:

1、<< 与 >> 不要写反

2、左右区间分别是[l, m] 和 [m + 1, r] m后面的+1不要忘记

3、pushdown 不要忘记删除父节点的标记

4、节点信息个数与赋值时的个数要匹配

5、想好要不要加 &

6、建树时除了叶节点,其他节点不要忘记赋值!

单点修改,单点查询

区间最后L个最大数

1275. 最大数 - AcWing题库

#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;
}

区间最大连续子段和

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

#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;
}    
/*

*/

区间最大公约数

246. 区间最大公约数 - AcWing题库

#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;
}    
/*

*/

区间修改,区间查询

涉及懒标记

区间加,查询区间和

243. 一个简单的整数问题2 - AcWing题库

#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;
}    
/*

*/

区间加乘,查询区间和

1277. 维护序列 - AcWing题库

#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轴上建立线段树,线段树维护的节点代表一段区间)

247. 亚特兰蒂斯 - AcWing题库

#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;
}	
/*

*/
posted @ 2022-02-03 16:35  Yra  阅读(45)  评论(0)    收藏  举报