0
点赞
收藏
分享

微信扫一扫

数据结构-线段树

王传学 2024-03-11 阅读 57

📑前言

本文主要是【线段树】——线段树简单使用的文章,如果有什么需要改进的地方还请大佬指出⛺️

目录

[1-9]线段树图示

在这里插入图片描述

例题

1208.小球与盒子

package 难点攻克;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
/**
 * 线段树一般需要四个函数,build(root,l,n)建树函数,modify(root,x,k)修改函数
 * query(root,l,r)查询函数,pushup(root)更新函数
 * 单点修改:修改某个点的值,区间查询,查询某个区间内的值(min,max,sum)
 * 线段树比树状数组更强大
 *
 */
public class 小球与盒子 {
	static class node{
		int l,r;
		long v;
	}
	
	static node tree[];

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		sc.nextToken();
		int n = (int)sc.nval;
		sc.nextToken();
		int m = (int)sc.nval;
		tree = new node[n*4];
		build(1, 1, n);//建树
		while(m-->0) {
			sc.nextToken();
			int op = (int)sc.nval;
			sc.nextToken();
			int x = (int)sc.nval;
			sc.nextToken();
			int y = (int)sc.nval;
			if (op==1) {
				modify(1, x, y);//单点修改,单点修改时是x加上y
			}else {
				System.out.println(query(1, x, y));//区间查询
			}
		}
	}
	//建树函数
	public static void build(int u,int l,int r) {
		tree[u] = new node();//申请空间
		if (l == r) {//叶子节点
			tree[u].l=l;
			tree[u].r=r;
		}else {
			tree[u].l=l;
			tree[u].r=r;
			int mid = (l+r)/2;
			build(2*u, l, mid);//递归左节点,建立左子树
			build(2*u+1, mid + 1, r);//递归右节点,建立右子树
		}
	}
	
	public static long query(int u,int l,int r) {
		if(l <= tree[u].l && r>=tree[u].r) {
			return tree[u].v;
		}
		long res = 0;
		int mid = (tree[u].l + tree[u].r) / 2;
		if(l <= mid) {
			//往左边走,往右边走
			res = query(u*2, l, r);
		}
		if(r > mid) {
			res += query(u*2+1, l, r);
		}
		return res;
	}
	
	public static void modify(int u,int x,long k) {
		if(tree[u].l == tree[u].r) {
			tree[u].v += k;
		}else {
			int mid = (tree[u].l+tree[u].r)/2;
			//遍历左右子树,进行单点修改的更新
			if(x<=mid) {
				modify(u*2, x, k);
			}else {
				modify(u*2+1, x, k);
			}
			push(u);//更新u
		}
	}
	
	public static void push(int u) {
		tree[u].v = tree[u*2].v + tree[u*2+1].v;
	}

}

📑文章末尾

在这里插入图片描述

举报

相关推荐

0 条评论