题意:n个数 m次操作
操作分别为
C l r d: 把区间[l, r] 加 d
Q l r : 查询区间[l, r]的和
H l r t: 查询时间t的时候[l, r]的和
B t: 回到时间t
思路:主席树区间修改,区间求和
const int maxn = + ;
const int maxnode = * maxn; int n, m; struct Node
{
int l, r;
LL sum, add;
} tr[maxnode];
int tail;
LL a[maxn];
LL qL, qR, value;
LL sum; #define lson tr[o].l,L,M
#define rson tr[o].r,M+1,R
#define self o,L,R
#define lc tr[o].l
#define rc tr[o].r void build(int o, int L, int R)
{
if (L == R)
{
tr[o].sum = a[L];
return;
}
tr[o].l = ++tail;
tr[o].r = ++tail;
int M = L + (R - L) / ;
build(lson);
build(rson);
tr[o].sum = tr[lc].sum + tr[rc].sum;
} void maintain(int o, int L, int R)
{
if (L < R)
{
tr[o].sum = tr[lc].sum + tr[rc].sum;
}
else tr[o].sum = a[L];
tr[o].sum += tr[o].add * (R - L + );
} void update(int& o, int L, int R)
{
tr[++tail] = tr[o];
o = tail;
if (qL <= L && R <= qR)
{
tr[o].add += value;
}
else
{
int M = L + (R - L) / ;
if (qL <= M) update(lson);
if (qR > M) update(rson);
}
maintain(self);
} void query(int o, int L, int R, int add)
{
if (qL <= L && R <= qR)
{
sum += tr[o].sum + add * (R - L + );
return;
}
int M = L + (R - L) / ;
if (qL <= M) query(lson, add + tr[o].add);
if (qR > M) query(rson, add + tr[o].add);
} int root[maxn];//表示第i个线段树的root是什么,显然root[0]=0 void init()
{
memset(tr, , sizeof(tr));
tail = ;
for (int i = ; i <= n; i++)
{
scanf("%lld", &a[i]);
}
root[] = ;
build(, , n);
} void solve()
{
char op[];
int t;
int i = ;
while (m--)
{
op[] = ;
scanf("%s", op);
if (op[] == 'Q')
{
scanf("%lld%lld", &qL, &qR);
sum = ;
query(root[i], , n, );
printf("%lld\n", sum); }
else if (op[] == 'C')
{
i++;
root[i] = root[i-];
scanf("%lld%lld%lld", &qL, &qR, &value);
update(root[i], , n);
}
else if (op[] == 'H')
{
scanf("%lld%lld%d", &qL, &qR, &t);
sum = ;
query(root[t], , n, );
printf("%lld\n", sum);
}
else
{
scanf("%d", &t);
i = t;
}
}
} int main()
{
while (scanf("%d%d", &n, &m) == )
{
init();
solve();
}
return ;
}