Question:
There are three operations to maintain An ordered series {:
1. Add an element.
2. delete an element.
3. Calculate the sum of the subscript % 5 = 3 in the series.
Solution:
I finally understood the various solutions.
Because the line segment tree does not support addition or deletion, the topic solution adopts the offline method.
Let's see how it solves the problem of adding and deleting.
First, record all the numbers that have occurred, sort and deduplicate them, and create a tree based on the de-duplicated result. Then, each operand will correspond to a point in the line segment tree.
When adding or deleting a node, you only need to change the value of the node and handle the impact of the node on the lower mark.
So how can we deal with the impact of these operations on the lower mark?
Now we want to consider a parent interval. Assume that its left and right subintervals have been updated.
Obviously, the subscript % 5 in the left interval is exactly the same as that in the parent interval % 5;
However, the subscript in the right interval is not necessarily the same, because the subscript in the right interval starts with mid as 1.
So long as we know the number of valid elements in the left interval cnt, we can know that the subscript I in the right interval corresponds to the subscript I + cnt in the parent interval.
Therefore, although we only need the sum of subscripts % 5 = 3 in the total interval. However, when updating an update, we need to know all the situations in the right range % 5.
Therefore, we need to open a sum [5] and a cnt for each node in the online segment tree to record the number of valid elements and the five cases of subscript % 5 in this node respectively.
When querying, you can directly access the sum [3] of the total interval.
In this way, the question can be solved. Complexity O (M logN ).
[Cpp]
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
Using namespace std;
# Define N 100003
# Define L (x) (x <1)
# Define R (x) (x <1 | 1)
# Define MID (x, y) (x + y)> 1)
Typedef _ int64 LL;
Int num [N], x [N]; // The number of operations corresponding to the num record, and the number of intervals corresponding to the x record
Int add;
Struct Tnode
{
Int l, r, cnt;
LL sum [5];
} T [N <2];
Void Build (int u, int l, int r)
{
T [u]. l = l, T [u]. r = r;
If (l = R-1)
{
Memset (T [u]. sum, 0, sizeof (T [u]. sum ));
T [u]. cnt = 0;
Return;
}
Int mid = MID (l, r );
Build (L (u), l, mid );
Build (R (u), mid, r );
Memset (T [u]. sum, 0, sizeof (T [u]. sum ));
T [u]. cnt = 0;
}
Void Updata (int u, int l, int r)
{
Add? ++ T [u]. cnt: -- T [u]. cnt;
If (T [u]. l = T [u]. r-1)
{
T [u]. sum [1] = add * x L-1];
Return;
}
Int mid = MID (T [u]. l, T [u]. r );
If (l> = mid)
Updata (R (u), l, r );
Else
Updata (L (u), l, r );
For (int I = 0; I <5; I ++)
{
Int j = (I + T [L (u)]. cnt) % 5;
T [u]. sum [j] = T [L (u)]. sum [j] + T [R (u)]. sum [I];
}
}
Int main ()
{
Int Q;
Char cmd [N], ccmd [4];
While (~ Scanf ("% d", & Q ))
{
Int top = 0;
For (int I = 0; I <Q; I ++)
{
Scanf ("% s", ccmd );
Cmd [I] = ccmd [0];
If (cmd [I]! ='S ')
Scanf ("% d", & num [top ++]);
}
Memcpy (x, num, sizeof (int) * top );
Sort (x, x + top );
Int n = unique (x, x + top)-x;
Build (1, 1, n + 1 );
For (int I = 0, j = 0; I <Q; I ++)
{
If (cmd [I] ='s ')
{
Printf ("% I64d \ n", T [1]. sum [3]);
Continue;
}
Int k = lower_bound (x, x + n, num [j ++])-x + 1;
Add = cmd [I] = 'A '? 1: 0;
Updata (1, k, k + 1 );
}
}
Return 0;
}