POJ 3468 A Simple Problem with Integers(JAVA版)

POJ 3468 A Simple Problem with Integers

题目大意:用n个整数,给指定区间的数,每个数字加上某个数,或者求指定区间的和。

思路如下:线段树成段更新与区间求和的裸题~这题按通常来讲似乎是不会TLE的,但是还是可以用快速io或者lazy思想来加速。lazy就是在给区间[i,j]全体加上一个数时,只更新区间[i,j]及其上的节点,然后在这里做一个标记,当查询有需要调用下面节点的内容时,再把下面原本没有更新的地方更新了。

AC代码:

import java.util.Scanner;

public class Main
{
	static int maxn=100000;
	static long sum[]=new long[maxn<<2];
	static long lazy[]=new long[maxn<<2];
	static Scanner scan=new Scanner(System.in);
	
	public static void buildTree(int l, int r, int rt)
	{
		if(l==r){sum[rt]=scan.nextInt();return;}
		
		int mid=(l+r)>>1;
		buildTree(l, mid, rt<<1);
		buildTree(mid+1, r, rt<<1|1);
		pushUp(rt);
	}
	
	public static void upDate(int L, int R, int add, int l, int r, int rt)
	{
		if(L<=l && r<=R)
		{
			sum[rt]+=(r-l+1)*add;
			lazy[rt]+=add;
			return;
		}
		
		pushDown(rt, r-l+1);//检查是否需要往下更新,因为下面的两个if需要用到rt的两个子节点的内容
		
		int mid=(l+r)>>1;
		if(L<=mid) upDate(L, R, add, l, mid, rt<<1);
		if(R>mid) upDate(L, R, add, mid+1, r, rt<<1|1);
		pushUp(rt);
	}
	
	public static void pushUp(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
	
	public static void pushDown(int rt, int m)
	{
		if(lazy[rt]!=0)//此处等于0时即不需要往下更新,无可更新内容
		{
			sum[rt<<1]+=lazy[rt]*(m-(m>>1));
			sum[rt<<1|1]+=lazy[rt]*(m>>1);
			lazy[rt<<1]+=lazy[rt];
			lazy[rt<<1|1]+=lazy[rt];
			lazy[rt]=0;
		}
	}
	
	public static long query(int L, int R, int l, int r, int rt)
	{
		if(L<=l && r<=R) return sum[rt];
		
		pushDown(rt, r-l+1);//检查是否需要往下更新,因为下面的两个if需要用到rt的两个子节点的内容

		int mid=(l+r)>>1;
		long sum=0;
		if(L<=mid) sum+=query(L, R, l, mid, rt<<1);
		if(R>mid) sum+=query(L, R, mid+1, r, rt<<1|1);
		return sum;
	}
	
	public static void main(String[] args)
	{
		int n=scan.nextInt();
		int m=scan.nextInt();
		buildTree(1, n, 1);	
		while(m-->0)
		{
			String key=scan.next();
			int a=scan.nextInt();
			int b=scan.nextInt();
			if(key.charAt(0)=='Q')
				System.out.println(query(a, b, 1, n, 1));
			if(key.charAt(0)=='C')
			{
				int c=scan.nextInt();
				upDate(a, b, c, 1, n, 1);
			}
		}
	}
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值