A Simple Problem with Integers (线段树--区间更新,区间求和)

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 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.

题意:区间更新和区间查询

 讲解博客:https://blog.csdn.net/daoshen1314/article/details/102790845

代码:

  



import java.util.Scanner;

public class Main{
	static final int max=100005;
	static long arr[]=new long[max];
	static long tree[]=new long[4*max];
	static long lazy[]=new long[4*max];
	static int n,q;
	public static void build(int node,int l,int r){
		 if(l==r){
			 tree[node]=arr[r];
		 }
		 else{
			 int mid=(l+r)/2;
			 int left_node=2*node+1;
			 int right_node=2*node+2;
			 build(left_node,l,mid);
			 build(right_node,mid+1,r);
			 tree[node]=tree[left_node]+tree[right_node];
		 }
	}
	public static void pushdown(int node,int l,int r){
		if(lazy[node]==0){
			return;
		}
		else{
			int mid=(l+r)/2;
			int left_node=2*node+1;
			int right_node=2*node+2;
			tree[left_node]+=lazy[node]*(mid-l+1);
			lazy[left_node]+=lazy[node];
			tree[right_node]+=lazy[node]*(r-mid);
			lazy[right_node]+=lazy[node];
			lazy[node]=0;
		}
	}
	public static void update(int node,int l,int r,int a,int b,long c){
		 if(l>=a&&r<=b){
			 tree[node]+=(r-l+1)*c;
			 lazy[node]+=c;
			 return;
		 }
		 pushdown(node,l,r);
		 int mid=(l+r)/2;
		 int left_node=2*node+1;
		 int right_node=2*node+2;
		 if(b<=mid){
			 update(left_node,l,mid,a,b,c);
		 }
		 else if(a>mid){
			 update(right_node,mid+1,r,a,b,c);
		 }
		 else{
			 update(left_node,l,mid,a,b,c);
			 update(right_node,mid+1,r,a,b,c);
		  }
		 tree[node]=tree[left_node]+tree[right_node];
	}
	public static long query(int node,int l,int r,int a,int b){
		 if(l>=a&&r<=b){
			 return tree[node];
		 }
		pushdown(node,l,r);
		int mid=(l+r)/2;
		int left_node=2*node+1;
		int right_node=2*node+2;
		if(b<=mid) return query(left_node,l,mid,a,b);
		else if(a>mid) return query(right_node,mid+1,r,a,b);
		else return query(left_node,l,mid,a,b)+query(right_node,mid+1,r,a,b);
   }
   public static void main(String[] args) {
	    Scanner scan=new Scanner(System.in);
	    n=scan.nextInt();
	    q=scan.nextInt();
	    for(int i=0;i<n;i++){
	    	arr[i]=scan.nextLong();
	    }
	    build(0,0,n-1);
	    while(q!=0){
	    	String s=scan.next();
	    	if(s.charAt(0)=='Q'){
	    		int a=scan.nextInt();
	    		int b=scan.nextInt();
	    		System.out.println(query(0,0,n-1,a-1,b-1));
	    	}
	    	else{
	    		int a=scan.nextInt();
	    		int b=scan.nextInt();
	    		long c=scan.nextLong();
	    		update(0,0,n-1,a-1,b-1,c);
	    	}
	    	q--;
	    }
}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼爱吃火锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值