• POJ 3468


    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.

    您有N个整数A1,A2,…,AN。 您需要处理两种操作。 一种操作类型是在给定间隔内向每个数字添加一些给定数字。 另一种是在给定的时间间隔内求和。

    输入值
    第一行包含两个数字N和Q。1≤N,Q≤100000。
    第二行包含N个数字,即A1,A2,…,AN的初始值。 -1000000000≤Ai≤1000000000。
    接下来的每条Q线代表一个操作。
    “ C a b c”是指将c加到Aa,Aa + 1,…,Ab中的每一个上。 -10000≤c≤10000。
    “ Q a b”是指查询Aa,Aa + 1,…,Ab的和。

    输出量
    您需要依次回答所有Q命令。 一行回答。

    输入
    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
    输出
    4
    55
    9
    15
    提示
    总和可能超出32位整数的范围。

    题目大意:
    输入n和m,表示n个数和m个询问,对于每个询问:

    • “ C a b c”是指将c加到Aa,Aa + 1,…,Ab中的每一个上。 -10000≤c≤10000。
    • “ Q a b”是指查询Aa,Aa + 1,…,Ab的和。

    当遇到Q的时候输出区间的和。

    解题思路:
    这道题是线段树的一道区间求和和区间更新,因为在区间更新时,普通遍历线段树一定会超时,我们这里用一个lazy数组用于存放要更新的值,每次用到这个值的时候再分配到子节点,我们什么时候用到这个区间什么时候就把lazy的值下放到子节点,举个例子,比如一共有12个数,第一次给 [ 1 6 ] 每一个加3,就让这个节点的lazy值为3,就不往下放了,当再次操作和1-6区间有重合时,再把这个节点的lazy值下放到子节点。关于lazy数组:因为一个树中有好几个元素,所以我们用结构体存储这棵树,我们要存放当前节点的值,当前节点的lazy值和区间长度,为什么要存区间长度,因为在给这个点的lazy赋值时,这个点的和一定会加上区间长度*lazy值,因为区间长度即是要更新值的个数。就一定不会超时。AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll _max=1e5+50;
    ll arr[_max];
    struct ttt
    {
    	ll lazy,sum;
    	int len;
    }tree[5*_max];
    int main()
    {
    	void build_tree(int,int,int);
    	ll query(int,int,int,int,int);
    	void update(int,int,int,int,int,int);
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for ( int i = 0; i < n; i++)
    	  scanf("%lld",&arr[i]);
    	getchar();
    	build_tree(0,0,n-1);
    	while(m--)
    	{
    		char k;
    		int a,b,c;
    		scanf("%c",&k);
    		if(k=='Q')
    		{
    			scanf("%d%d",&a,&b);
    			getchar();
    			ll sum=query(0,0,n-1,a-1,b-1);
    			printf("%lld
    ",sum);
    		}
    		else
    		{
    			scanf("%d%d%d",&a,&b,&c);
    			getchar();
    			update(0,0,n-1,a-1,b-1,c);
    		}
    	}
     	//system("pause");
    	return 0;
    }
    void build_tree(int node ,int start ,int end)
    {
    	tree[node].lazy=0;
    	tree[node].len=end-start+1;
    	if(start==end)
    	{
    		tree[node].sum=arr[start];
    		return;
    	}
    	int ln = node*2+1;
    	int rn = node*2+2;
    	int mid=(start+end)>>1;
    	build_tree(ln,start,mid);
    	build_tree(rn,mid+1,end);
    	tree[node].sum=tree[ln].sum+tree[rn].sum;
    }
    void lazzy(int node)
    {
    	if(tree[node].lazy)
    	{
    		tree[node*2+1].lazy+=tree[node].lazy;
    		tree[node*2+2].lazy+=tree[node].lazy;
    		tree[node*2+1].sum+=tree[node].lazy*tree[node*2+1].len;
    		tree[node*2+2].sum+=tree[node].lazy*tree[node*2+2].len;
    		tree[node].lazy=0;
    	}
    }
    ll query(int node, int start, int end, int l, int r)
    {
    	if (l<=start&&r>=end)
          return tree[node].sum;
    	lazzy(node);
        int ln=node*2+1;
        int rn=node*2+2;
        int mid=(start+end)>>1;
    	ll suml,sumr;
    	suml=sumr=0;
    	if(l<=mid)
          suml=query(ln,start,mid,l,r);
        if(r>mid)
    	  sumr=query(rn,mid+1,end,l,r);
        return suml+sumr;
    }
    void update(int node,int start,int end,int l,int r,int x)
    {
    	if(l<=start&&r>=end)
    	{
    		tree[node].lazy+=x;
    		tree[node].sum+=x*tree[node].len;
    		return;
    	}
    	lazzy(node);
    	int ln=node*2+1;
        int rn=node*2+2;
    	int mid=(start+end)>>1;
    	if(l<=mid)
    	  update(ln,start,mid,l,r,x);
    	if(r>mid)
    	  update(rn,mid+1,end,l,r,x);
    	tree[node].sum=tree[ln].sum+tree[rn].sum;
    }
    
  • 相关阅读:
    Java——快速排序
    Java——归并排序
    Java——递归
    Java——希尔排序
    Java——插入排序
    Java——选择排序
    ES6快速入门
    ECharts is not Loaded
    scoped的规则
    css哪些样式属性可以继承
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294277.html
Copyright © 2020-2023  润新知