You cannot update all segments in a tree segment immediately. You must perform delayed operations. In fact, it is for each node, and another domain to indicate the delay
Number of updates. Then, during the update operation and search operation, the Father's Day's latency domain is moved to the two sons.
This question requires added value in segments. Therefore, when writing the PushDown function, you must add the Father's Day stress value to the son node.
Multiply by the length of the son interval. This question seems to be possible with a tree array, but the solution is certainly not so straightforward. However, the speed will certainly be faster.
Most popular solutions on line segment trees are arrays with up to four times the number of nodes opened. Position 1 is used as the root, and each position actually represents a range.
A Person Position 1 represents 1-N or 0-(N-1) range, specific to the question. Then 2 represents the range 1-(1 + N)/2,3 represents the range (1 + N)/2 + 1-N.
As for lazy marking, it makes a big array. The meaning is the same as that of the Line Segment tree array. After it is clear, it is easy to write. The most important thing is deformation.
Solve some strange problems.
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
Using namespace std;
Typedef long INT;
Const INT MAX_N = 100010;
Const int inf = 0x7ffffffffffffll;
INT nTree [MAX_N <2];
INT nAdd [MAX_N <2];
INT nN, nQ;
Void PushUp (INT nRt)
{
NTree [nRt] = nTree [nRt <1] + nTree [nRt <1 | 1];
}
Void BuildTree (INT nL, INT nR, INT nRt)
{
NAdd [nRt] = 0;
If (nL = nR)
{
Scanf ("% I64d", & nTree [nRt]);
Return;
}
INT nMid = (nL + nR)> 1;
BuildTree (nL, nMid, nRt <1 );
BuildTree (nMid + 1, nR, nRt <1 | 1 );
PushUp (nRt );
}
Void PushDown (INT nL, INT nR, INT nRt)
{
INT nMid = (nL + nR)> 1;
INT nLs = nRt <1;
INT nRs = nLs | 1;
If (nAdd [nRt])
{
NAdd [nLs] + = nAdd [nRt];
NAdd [nRs] + = nAdd [nRt];
NTree [nLs] + = (nMid-nL + 1) * nAdd [nRt];
NTree [nRs] + = (nR-nMid) * nAdd [nRt];
NAdd [nRt] = 0;
}
}
Void Update (INT nL, INT nR, INT nRt, INT nX, INT nY, INT nV)
{
If (nL> = nX & nR <= nY)
{
NTree [nRt] + = nV * (nR-nL + 1 );
NAdd [nRt] + = nV;
Return;
}
PushDown (nL, nR, nRt );
INT nMid = (nL + nR)> 1;
If (nX <= nMid) Update (nL, nMid, nRt <1, nX, nY, nV );
If (nY> nMid) Update (nMid + 1, nR, nRt <1 | 1, nX, nY, nV );
PushUp (nRt );
}
INT Query (INT nL, INT nR, INT nRt, INT nX, INT nY)
{
If (nL> = nX & nR <= nY)
{
Return nTree [nRt];
}
PushDown (nL, nR, nRt );
INT nAns = 0;
INT nMid = (nL + nR)> 1;
If (nX <= nMid) nAns + = Query (nL, nMid, nRt <1, nX, nY );
If (nY> nMid) nAns + = Query (nMid + 1, nR, nRt <1 | 1, nX, nY );
Return nAns;
}
Int main ()
{
INT nTemp;
While (scanf ("% I64d % I64d", & nN, & nQ) = 2)
{
BuildTree (1, nN, 1 );
While (nQ --)
{
Char szCmd [10];
INT nX, nY, nV;
Scanf ("% s", szCmd );
If (szCmd [0] = 'q ')
{
Scanf ("% I64d % I64d", & nX, & nY );
Printf ("% I64d \ n", Query (1, nN, 1, nX, nY ));
}
Else
{
Scanf ("% I64d % I64d % I64d", & nX, & nY, & nV );
Update (1, nN, 1, nX, nY, nV );
}
}
}
Return 0;
}