Loading

POJ-3468 A Simple Problem with Integers

A Simple Problem with Integers

线段树 || 分块

模板题

线段树:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
ll num[maxn];

struct node
{
	int l;
	int r;
	ll val;
	ll lazy;
}tree[maxn * 4];

void build(int x, int l, int r)
{
	tree[x].l = l;
	tree[x].r = r;
	tree[x].lazy = 0;
	if (l == r)
	{
		tree[x].val = num[l];
		return;
	}
	int mid = l + r >> 1;
	build(x << 1, l, mid);
	build(x << 1 | 1, mid + 1, r);
	tree[x].val = tree[x << 1].val + tree[x << 1 | 1].val;
}

void pushdown(int x)
{
	if (tree[x].lazy)
	{
		int a = x << 1;
		int b = x << 1 | 1;
		tree[a].val += (tree[a].r - tree[a].l + 1) * tree[x].lazy;
		tree[b].val += (tree[b].r - tree[b].l + 1) * tree[x].lazy;
		tree[a].lazy += tree[x].lazy;
		tree[b].lazy += tree[x].lazy;
		tree[x].lazy = 0;
	}
}

void update(int x, int l, int r, int val)
{
	if (tree[x].l >= l && tree[x].r <= r)
	{
		tree[x].val += (tree[x].r - tree[x].l + 1) * val;
		tree[x].lazy += val;
		return;
	}
	pushdown(x);
	int mid = tree[x].l + tree[x].r >> 1;
	if (l <= mid)
		update(x << 1, l, r, val);
	if (r > mid)
		update(x << 1 | 1, l, r, val);
	tree[x].val = tree[x << 1].val + tree[x << 1 | 1].val;
}

ll query(int x, int l, int r)
{
	if (tree[x].l >= l && tree[x].r <= r)
		return tree[x].val;
	pushdown(x);
	ll ans = 0;
	int mid = tree[x].l + tree[x].r >> 1;
	if (l <= mid)
		ans += query(x << 1, l, r);
	if (r > mid)
		ans += query(x << 1 | 1, l, r);
	return ans;
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%lld", &num[i]);
	build(1, 1, n);
	for (int i = 0; i < m; i++)
	{
		char s[5];
		int a, b;
		scanf("%s%d%d", s, &a, &b);
		if (a > b)swap(a, b);
		if (s[0] == 'Q')
			printf("%lld\n", query(1, a, b));
		else if (s[0] == 'C')
		{
			int c;
			scanf("%d", &c);
			update(1, a, b, c);
		}
	}
}

分块:(参考的是蓝书的代码)

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll num[maxn], sum[maxn], add[maxn], pos[maxn], R[maxn], L[maxn];

void update(int l, int r, ll val)
{
    int p = pos[l], q = pos[r];
    if(p == q)
    {
        for(int i=l; i<=r; i++) num[i] += val;
        sum[q] += (r - l + 1) * val;
    }
    else
    {
        for(int i=p+1; i<q; i++) add[i] += val;
        for(int i=l; i<=R[p]; i++) num[i] += val;
        sum[p] += val * (R[p] - l + 1);
        for(int i=L[q]; i<=r; i++) num[i] += val;
        sum[q] += val * (r - L[q] + 1);
    }
}

ll query(int l, int r)
{
    ll ans = 0;
    int p = pos[l], q = pos[r];
    if(p == q)
    {
        for(int i=l; i<=r; i++)
            ans += num[i];
        ans += add[p] * (r - l + 1);
    }
    else
    {
        for(int i=p+1; i<q; i++) ans += add[i] * (R[i] - L[i] + 1) + sum[i];
        for(int i=l; i<=R[p]; i++) ans += num[i];
        ans += add[p] * (R[p] - l + 1);
        for(int i=L[q]; i<=r; i++) ans += num[i];
        ans += add[q] * (r - L[q] + 1);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> num[i];
    int t = (double)sqrt((double)n);
    for(int i=1; i<=t; i++)
    {
        L[i] = R[i-1] + 1;
        R[i] = i * t;
    }
    if(R[t] < n)
    {
        t++;
        L[t] = R[t-1] + 1;
        R[t] = n;
    }
    for(int i=1; i<=t; i++)
    {
        for(int j=L[i]; j<=R[i]; j++)
        {
            sum[i] += num[j];
            pos[j] = i;
        }
    }
    
    while(m--)
    {
        char x;
        int l, r;
        cin >> x >> l >> r;
        if(x == 'C')
        {
            ll val;
            cin >> val;
            update(l, r, val);
        }
        else
            cout << query(l, r) << endl;
    }
    return 0;
}
posted @ 2022-05-19 19:25  dgsvygd  阅读(12)  评论(0编辑  收藏  举报