标签:
题意:有n个操作,操作种类有A a b表示把区间[a,b]的值依次加1 2 … b-a+1,操作B a b表示把区间[a,b]的值依次加b-a+1… 2 1,操作C a b x表示把区间[a,b]的值全部替换为x,操作S a b要求输出区间[a,b]里的所有数字的和。
题解:A和B操作都是把区间内加上一个等差数列,所以要用线段树维护每个区间所要加的等差数列的首项还有公差,注意操作C里的x还可以取负值和0,所以需要再添加一个标记数组flag。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 250005;
ll tree[N << 2], setv[N << 2], a0[N << 2], d[N << 2];
int flag[N << 2];
char op[5];
void pushdown(ll k, ll left, ll right) {
if (flag[k]) {
ll len = right - left + 1;
setv[k * 2] = setv[k * 2 + 1] = setv[k];
flag[k * 2] = flag[k * 2 + 1] = flag[k];
tree[k * 2] = setv[k] * (len - len / 2);
tree[k * 2 + 1] = setv[k] * (len / 2);
d[k * 2] = d[k * 2 + 1] = a0[k * 2] = a0[k * 2 + 1] = 0;
flag[k] = 0;
}
if (a0[k] || d[k]) {
d[k * 2] += d[k];
d[k * 2 + 1] += d[k];
a0[k * 2] += a0[k];
ll mid = (right + left) / 2;
ll a1 = a0[k] + d[k] * (mid - left + 1);
ll nl = mid - left + 1, nr = right - mid;
tree[k * 2] += a0[k] * nl + nl * (nl - 1) / 2 * d[k];
a0[k * 2 + 1] += a1;
tree[k * 2 + 1] += a1 * nr + nr * (nr - 1) / 2 * d[k];
a0[k] = d[k] = 0;
}
}
void pushup(ll k) {
tree[k] = tree[k * 2] + tree[k * 2 + 1];
}
void modify(ll k, ll left, ll right, ll l, ll r, ll dd) {
if (l <= left && right <= r) {
ll st;
if (dd >= 0)
st = left - l + 1;
else
st = r - left + 1;
a0[k] += st, d[k] += dd;
ll n = right - left + 1;
tree[k] += st * n + n * (n - 1) / 2 * dd;
return;
}
pushdown(k, left, right);
int mid = (left + right) / 2;
if (l <= mid)
modify(k * 2, left, mid, l, r, dd);
if (r > mid)
modify(k * 2 + 1, mid + 1, right, l, r, dd);
pushup(k);
}
void modify2(ll k, ll left, ll right, ll l, ll r, ll x) {
if (l <= left && right <= r) {
flag[k] = 1;
setv[k] = x;
tree[k] = x * (right - left + 1);
a0[k] = d[k] = 0;
return;
}
pushdown(k, left, right);
ll mid = (left + right) / 2;
if (l <= mid)
modify2(k * 2, left, mid, l, r, x);
if (r > mid)
modify2(k * 2 + 1, mid + 1, right, l, r, x);
pushup(k);
}
ll query(ll k, ll left, ll right, ll l, ll r) {
if (l <= left && right <= r)
return tree[k];
pushdown(k, left, right);
ll mid = (left + right) / 2, res = 0;
if (l <= mid)
res += query(k * 2, left, mid, l, r);
if (r > mid)
res += query(k * 2 + 1, mid + 1, right, l, r);
pushup(k);
return res;
}
int main() {
int t;
ll x, l, r;
scanf("%d", &t);
memset(tree, 0, sizeof(tree));
memset(a0, 0, sizeof(a0));
memset(d, 0, sizeof(d));
memset(flag, 0, sizeof(flag));
while (t--) {
scanf("%s%lld%lld", op, &l, &r);
if (op[0] == ‘A‘)
modify(1, 1, N - 1, l, r, 1);
else if (op[0] == ‘B‘)
modify(1, 1, N - 1, l, r, -1);
else if (op[0] == ‘C‘) {
scanf("%lld", &x);
modify2(1, 1, N - 1, l, r, x);
}
else
printf("%lld\n", query(1, 1, N - 1, l, r));
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/hyczms/article/details/47813307