Poj 3468 is actually a basic line segment tree question.
If the line segment tree is constructed, it will definitely be TLE. The idea of optimizing this question is,
When you insert a number, you do not need to insert the number to the leaf node.
The range is inserted into this range, and an incremental record is used. If there is an inquiry at the moment
If this range is suitable for the query range, add the value of the original node directly.
Increment multiplied by the range and then added to sum. If the range of this node is not suitable for query
If you want to query the scope of the query, You have to query its subnodes. Then, we will pass this increment.
Give it a subnode, so that the time efficiency will be relatively high.
# Include <stdio. h>
# Include <string. h>
# Include <stdlib. h>
Struct point
{
_ Int64 X, Y, sum, add; // Add the added value of the record.
} A [600000];
_ Int64 B [600006];
Void tree (_ int64 t ,__ int64 x ,__ int64 y) // first build a sum tree using recursive ideas, first consider the root node and then the left and right Child Nodes
{
A [T]. x = X;
A [T]. Y = y;
A [T]. Add = 0;
If (x = y)
{
A [T]. Sum = B [X]; // returns the value assigned when a leaf node is created.
Return;
}
_ Int64 mid = (x + y)/2;
_ Int64 temp = 2 * t;
Tree (temp, X, mid );
Tree (temp + 1, Mid + 1, y );
A [T]. Sum = A [temp]. Sum + A [temp + 1]. sum;
}
Void Update (_ int64 t ,__ int64 x ,__ int64 y ,__ int64 Val)
{
If (A [T]. x = x & A [T]. Y = y)
{
A [T]. Add + = val; // Save the added value to add and return
Return;
}
A [T]. sum = A [T]. sum + val * (Y-x + 1); // modify the sum value of the current node because only [, b] The Val times of the number in the interval, so tree [k] is used. sum = tree [K]. sum + val * (B-A + 1 );
_ Int64 mid = (a [T]. x + A [T]. Y)/2;
_ Int64 temp = 2 * t;
If (Y <= mid)
Update (temp, X, Y, Val );
Else if (x> mid)
Update (temp + 1, x, y, Val );
Else
{
Update (temp, X, mid, Val );
Update (temp + 1, Mid + 1, Y, Val );
}
}
_ Int64 query (_ int64 t ,__ int64 x ,__ int64 y)
{
If (x = A [T]. X & Y = A [T]. y) // find that the node interval is the query interval and directly return its sum + (B-A + 1) * tree [K]. add
Return a [T]. Sum + (Y-x + 1) * A [T]. Add;
A [T]. Sum + = (a [T]. Y-A [T]. x + 1) * A [T]. Add;// If the sum value of the current node does not match, continue searching.
_ Int64 temp = 2 * t;
_ Int64 mid = (a [T]. x + A [T]. Y)/2;
Update (temp, a [T]. x, mid, a [T]. add); // update the sum and add values of the left and right subtree to find the position matching the range [a, B ].
Update (temp + 1, Mid + 1, a [T]. Y, a [T]. Add );
A [T]. Add = 0; // Add the value of the current node to 0, because the left and right subtree and the sum value of the current node have been updated.
If (mid> = y); // there are three types of queries: 1. [a, B] on the left subtree 2. [a, B] on the right subtree 3. [a, B] spans left and right Subtrees.
Return query (temp, x, y );
Else if (x> mid)
Return query (temp + 1, x, y );
Else
Return query (temp, X, mid) + query (temp + 1, Mid + 1, y );
}
Int main ()
{
_ Int64 m, n, I, j, A, B, Val;
While (scanf ("% i64d % i64d", & N, & M )! = EOF)
{
For (I = 1; I <= N; I ++)
{
Scanf ("% i64d", & B [I]);
}
Tree (1, 1, n );
While (M --)
{
Char C [100];
Scanf ("% s", C );
If (C [0] = 'C ')
{
Scanf ("% i64d % i64d % i64d", & A, & B, & Val );
Update (1, A, B, Val );
}
Else
{
Scanf ("% i64d % i64d", & A, & B );
Printf ("% i64d \ n", query (1, a, B ));
}
}
}
Return 0;
}
The key idea is to query functions. Updated only when the range to be queried is not the current value
The sum value of the current interval and the left and right intervals below it. Because the next search requires a smaller interval
That is, the left and right intervals of the current interval. You need to put the values added in this interval into the left and right subtree intervals respectively,
Make sure that the added value is always logged.
In this way, large to small updates can save the program's time efficiency. If you need to traverse all the intervals from the first update to the last update
To use this method, you only need to find the intervals that meet the conditions.