• POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)


    题目链接:http://poj.org/problem?id=3468


    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 56005   Accepted: 16903
    Case Time Limit: 2000MS

    Description

    You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of AaAa+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



    代码例如以下:
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    //lson和rson分辨表示结点的左儿子和右儿子
    //rt表示当前子树的根(root),也就是当前所在的结点
    #define LL long long
    const int maxn = 111111;
    //maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
    LL add[maxn<<2];
    LL sum[maxn<<2];
    void PushUp(int rt) //把当前结点的信息更新到父结点
    {
    	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void PushDown(int rt,int m)//把当前结点的信息更新给儿子结点
     {
    	if (add[rt]) 
    	{
    		add[rt<<1] += add[rt];
    		add[rt<<1|1] += add[rt];
    		sum[rt<<1] += add[rt] * (m - (m >> 1));
    		sum[rt<<1|1] += add[rt] * (m >> 1);
    		add[rt] = 0;
    	}
    }
    void build(int l,int r,int rt)
     {
    	add[rt] = 0;
    	if (l == r)
    	{
    		scanf("%lld",&sum[rt]);
    		return ;
    	}
    	int m = (l + r) >> 1;
    	build(lson);
    	build(rson);
    	PushUp(rt);
    }
    void update(int L,int R,int c,int l,int r,int rt) 
    {
    	if (L <= l && r <= R)
    	{
    		add[rt] += c;
    		sum[rt] += (LL)c * (r - l + 1);
    		return ;
    	}
    	PushDown(rt , r - l + 1);
    	int m = (l + r) >> 1;
    	if (L <= m)
    		update(L , R , c , lson);
    	if (m < R) 
    		update(L , R , c , rson);
    	PushUp(rt);
    }
    LL query(int L,int R,int l,int r,int rt)
     {
    	if (L <= l && r <= R)
    	{
    		return sum[rt];
    	}
    	PushDown(rt , r - l + 1);
    	int m = (l + r) >> 1;
    	LL ret = 0;
    	if (L <= m) 
    		ret += query(L , R , lson);
    	if (m < R)
    		ret += query(L , R , rson);
    	return ret;
    }
    int main() 
    {
    	int N , Q;
    	scanf("%d%d",&N,&Q);//N为节点数
    	build(1 , N , 1);
    	while (Q--)//Q为询问次数
    	{
    		char op[2];
    		int a , b , c;
    		scanf("%s",op);
    		if (op[0] == 'Q') 
    		{
    			scanf("%d%d",&a,&b);
    			printf("%lld
    ",query(a , b , 1 , N , 1));
    		}
    		else
    		{
    			scanf("%d%d%d",&a,&b,&c);//c为区间a到b添加的值
    			update(a , b , c , 1 , N , 1);
    		}
    	}
    	return 0;
    }
    
    



  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6731493.html
Copyright © 2020-2023  润新知