POJ 3468 A Simple Problem with Integers【Line Segment Tree】【Delay Marker】

Problem Portal: Click to open the link
A Simple Problem with Integers
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 129782   Accepted: 40297
Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

Source

POJ Monthly--2007.11.25 , Yang Yi

seems to be a very bare line segment tree problem, but if you use the line segment tree bare template directly, it will time out.
At this time, we need to use one of the most commonly used methods in line segment trees: delay markers.

(The following description is reproduced in https://blog.csdn.net/u012860063/article/details/38322283)

Interval update refers to updating the value of a leaf node in an interval, because more than one leaf node is involved, and a leaf node will affect its corresponding non-leaf parent node, so there will be many non-leaf nodes that need to be updated backtracking. If the update is done at one time, the time complexity of the operation is definitely not O(lgn). For example, when we want to update the leaf nodes in the interval [0, 3], we need to update all other nodes except leaf nodes 3, 9. To this end, the concept of delayed markers in the line segment tree is introduced, which is also the essence of the line segment tree.

Delay mark : each node adds a new mark to record whether the node has undergone some modification (this modification operation will affect its child nodes). For the modification of any interval, we first divide it into line segments according to the interval query method. Nodes in the tree, then modify the information of these nodes, and label these nodes with tags representing such modification operations. When modifying and querying, if we arrive at a node p and decide to consider its child nodes, then we need to see whether the node p is marked. If so, we need to modify the information of its child nodes according to the mark, and give the child nodes All are marked with the same mark, and the mark of node p is eliminated at the same time.


In this way, delayed marking can greatly reduce the time loss in the update operation. For example, the interval of the line segment tree is [1,10] If we only want to modify the interval [1,10], we only need to modify the first node, and do not need to update to a single node layer by layer. This saves a lot of time.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define LL long long
#define M(a,b) memset(a,b,sizeof(a))
const int MAXN=100005;
LL num[MAXN];
struct Node
{
    int l, r;
    int len;
    LL sum;
    LL late;
} tree[MAXN<<2];
void pushup(int root) ///Updating
{
    tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
}
void build(int root,int l,int r)
{
    tree[root].l=l;
    tree[root].r=r;
    tree[root].sum=0;
    tree[root].len=r-l+1;///Interval length
    if(tree[root].l==tree[root].r)
    {
        tree[root].sum=num[l];
        return ;
    }
    int mid = (l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);

    pushup(root);
}
void pushdown(int root)///Update down
{
    if(tree[root].late)///If the node is marked
    {
        tree[root<<1].sum +=tree[root].late*tree[root<<1].len;
        tree[root<<1|1].sum+=tree[root].late*tree[root<<1|1].len;
        tree[root<<1].late+=tree[root].late;///The mark is also inherited by child nodes
        tree[root<<1|1].late+=tree[root].late;///The mark is also inherited by child nodes
        tree[root].late = 0;
    }///Update only one level down
}
void update(int root,int l, int r,LL late)
{
    if(tree[root].l==l&&tree[root].r==r)///If the query interval is the same as the node interval, update the node directly
    {
        tree[root].sum+=(tree[root].len*late);
        tree[root].late+=late;///Mark the node
        return ;
    }
    pushdown(root);///Otherwise update down
    int mid = (tree[root].l+tree[root].r)>>1;
    if(mid>=r)
    {
        update(root<<1,l,r,late);
    }
    else if(l>mid)
    {
        update(root<<1|1,l,r,late);
    }
    else
    {
        update(root<<1,l,mid,late);
        update(root<<1|1,mid+1,r,late);
    }
    pushup(root);
}
LL query(int root,int l,int r)
{
   // printf("L==%d r==%d\n",l,r);
    if(tree[root].l==l&&tree[root].r==r)
    {
        return tree[root].sum;
    }
    pushdown(root);///When querying, also determine whether the node has a mark
    int mid  = (tree[root].l+tree[root].r)>>1;
    if(mid>=r)
    {
        return query(root<<1,l,r);
    }
    else if(l>mid)
    {
        return query(root<<1|1,l,r);
    }
    else
    {
        return (query(root<<1,l,mid)+query(root<<1|1,mid+1,r));
    }
}
intmain()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%lld",&num[i]);
        }
        getchar();
        build(1,1,n);
        char c1[3];
        int x,y;
        LL c;
        for(int i=0; i<m; i++)
        {
            scanf("%s",&c1);

            if(c1[0]=='Q')
            {
                scanf("%d %d",&x,&y);
                printf("%lld\n",query(1,x,y)) ;
            }
            else
            {
                scanf("%d %d %lld",&x,&y,&c);
                update(1,x,y,c);
            }
        }
    }
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325946210&siteId=291194637