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