HDU 1166 敌兵布阵 && HDU 1754 I Hate It(JAVA版)

HDU 1166 敌兵布阵

题目大意:普通的单点更新,区间求和问题。

思路如下:树状数组跟线段树都成,裸题,当然,用java的要快速io。

AC代码:(树状数组)

import java.io.*;

public class Main
{
	static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
	
	public static int nextInt()throws IOException {in.nextToken();return (int)in.nval;}
	
	public static String next()throws IOException {in.nextToken();return in.sval;}
	
	public static int lowbit(int x) {return x&(-x);}
	
	public static int sum(int x, int[] c)
	{
		int sum=0;
		for(int i=x;i>0;i-=lowbit(i))
			sum+=c[i];
		return sum;
	}
	
	public static void main(String[] args)throws IOException
	{
		int t=nextInt();
		int cas=0;
		while(t-->0)
		{
			int n=nextInt();
			int c[]=new int[n+1];
			for(int i=1;i<n+1;i++)
			{
				int num=nextInt();
				for(int j=i;j<n+1;j+=lowbit(j))
					c[j]+=num;
			}
			
			String str=next();
			out.println("Case "+(++cas)+":");
			while(str.charAt(0)!='E')
			{
				int a=nextInt();
				int b=nextInt();
				if(str.charAt(0)=='A' || str.charAt(0)=='S')
				{
					if(str.charAt(0)=='A');
					else{b=-b;}
					for(int i=a;i<n+1;i+=lowbit(i))
						c[i]+=b;
				}
				if(str.charAt(0)=='Q')
					out.println(sum(b, c)-sum(a-1, c));
				str=next();
			}
		}
		out.flush();
	}
}

AC代码:(线段树)

import java.io.*;

public class Main
{
	static int maxn=50000;
	static int sum[]=new int[maxn<<2];
	static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));;
	static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));;
	
	public static int nextInt()throws IOException {in.nextToken();return (int)in.nval;}
	
	public static String next()throws IOException {in.nextToken();return in.sval;}
	
	public static void buildTree(int l, int r, int rt)throws IOException
	{
		if(l==r) {sum[rt]=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 p, int add, int l, int r, int rt)
	{
		if(l==r) {sum[rt]+=add; return;}
		
		int mid=(l+r)>>1;
		if(p<=mid)
			upDate(p, add, l, mid, rt<<1);
		if(p>mid)
			upDate(p, 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 int query(int L, int R, int l, int r, int rt)
	{
		if(L<=l && r<=R) return sum[rt];
		
		int mid=(l+r)>>1, total=0;
		if(L<=mid) {total+=query(L, R, l, mid, rt<<1);}
		if(R>mid) {total+=query(L, R, mid+1, r, rt<<1|1);}
		
		return total;
	}

	public static void main(String[] args)throws IOException
	{
		int t=nextInt();
		int cas=0;
		while(t-->0)
		{
			out.println("Case "+(++cas)+":");
			int n=nextInt();
			buildTree(1, n, 1);
			String str=next();
			while(str.charAt(0)!='E')
			{
				int a=nextInt();
				int b=nextInt();
				if(str.charAt(0)=='Q')
					out.println(query(a, b, 1, n, 1));
				if(str.charAt(0)=='A')
					upDate(a, b, 1, n, 1);
				if(str.charAt(0)=='S')
					upDate(a, -b, 1, n, 1);
				str=next();
			}
		}
		out.flush();
	}
}


HDU 1754 I Hate It

题目大意:对区间里的某个值进行修改,并且求某个区间的最大值。

思路如下:明显是线段树的裸题,单点更新与区间求最大值。

AC代码:

import java.util.Scanner;

public class Main
{
	static int maxn=200000;
	static int max[]=new int[maxn<<2];
	static Scanner scan=new Scanner(System.in);
	
	public static void buildTree(int l, int r, int rt)
	{
		if(l==r){max[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 p, int change, int l, int r, int rt)
	{
		if(l==r){max[rt]=change;return;}
		
		int mid=(l+r)>>1;
		if(p<=mid) upDate(p, change, l, mid, rt<<1);
		if(p>mid) upDate(p, change, mid+1, r, rt<<1|1);
		pushUp(rt);
	}
	
	public static void pushUp(int rt){max[rt]=Math.max(max[rt<<1], max[rt<<1|1]);}
	
	public static int query(int L, int R, int l, int r, int rt)
	{
		if(L<=l && r<=R){return max[rt];}
		
		int mid=(l+r)>>1, max=0;
		if(L<=mid) max=Math.max(max, query(L, R, l, mid, rt<<1));
		if(R>mid) max=Math.max(max, query(L, R, mid+1, r, rt<<1|1));
		return max;
	}
	
	public static void main(String[] args)
	{
		while(scan.hasNext())
		{
			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)=='U')
					upDate(a, b, 1, n, 1);
			}
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值