• 线段树封装


    /*
    *
    * Name: Segment Tree
    * Copyright (C) 2017-2019 zhangtianli
    *
    */
    
    /*
    *
    * basic operation
    * 
    * - in main
    *   - tree "name"
    *   - init()  *important
    *	- build_single/_long()
    *	- operation by changing val in struct "tree"
    *   - used functions below
    *	** don't change the basic items
    *
    * functions:
    *
    *	1. void init(void)  make int Tree[] & add[]
    *
    *	2. void build_single(long long l, long long r, long long k)  bulid segnent tree by single update & query
    *      l , r : build tree from point "l" to point "r"
    *      k : start from which point number **should be 1 in defult
    *
    *   3. void bulid_long(long long l, long long r, long long k)  bulid segnent tree by long update & query
    *      l , r : build tree from point "l" to point "r"
    *      k : start from which point number **should be 1 in defult
    *
    *	4. void single_update(long long l, long long r, long long k, long long place, long long val) modify single element
    *      l , r : search from point "l" to point "r" **should be 1 & n (element number) in defult
    *      k : start point  **should be 1 in defult
    *      val : modify key (could be change into others)
    *
    *   5. void long_update(long long l, long long r, long long k, long long a, long long b, long long val)  modify elements in a section
    *      l , r : search from point "l" to point "r" **should be 1 & n (element number) in defult
    *      k : start point  **should be 1 in defult
    *      a , b : section's left point & right point
    *      val : modify key (could be change into others)
    *
    *   6. inline long long long_query_single(long long l, long long r, long long k, long long a, long long b) querying a section
    *      use with "build_single" & "single_update"
    *      l , r : search from point "l" to point "r" **should be 1 & n (element number) in defult
    *      k : start point  **should be 1 in defult
    *      a , b : section's left point & right point
    *      return : could be changed by user functions (basicly add and sum)
    *
    *   7. inline long long long_query_long(long long l, long long r, long long k, long long a, long long b) querying a section
    *      use with "long_build" & "long_update"
    *      l , r : search from point "l" to point "r" **should be 1 & n (element number) in defult
    *      k : start point  **should be 1 in defult
    *      a , b : section's left point & right point
    *      return : could be changed by user functions (basicly add and sum)
    *
    * user functions:
    *   changeable function **do not change 
    *   
    *   1. seted_single : use INF for normal
    *   2. max_len : max_len of tree **it will be times 4 automatically
    *   3. void make_tree_basic_single(long long x) last layer's operation in tree. used in "build_single"
    *   4. void make_tree_basic_long(long long x) last layer's operation in tree. used in "build_long"
    *   5. long long make_tree_single(long long l, long long r) normal point tree make. used in "build_single"
    *   6. long long make_tree_long(long long l, long long r) normal point tree make. used in "build_long"
    *   7. void update_single(long long pos, long long val) change single element used in "single_update" normally is Tree[pos] += val
    *      pos : place that change val
    *      val : val the change
    *   8. void update_long(long long pos, long long val) change single element used in "long_update" normally is add[pos] += val;
    *      pos : place that change val
    *      val : val the change
    *   9. inline long long comp_single(long long v1, long long v2) compare v1 & v2 used in "long_query_single"
    *      sum : return v1 + v2
    *      min : return std::min(v1, v2);
    *      max : return std::max(v1, v2);
    *   10. inline long long comp_long(long long v1, long long v2)  compare v1 & v2 used in "long_query_long"
    *      sum : return v1 + v2
    *      min : return std::min(v1, v2);
    *      max : return std::max(v1, v2);
    *
    */
    
    struct tree {
    // basic items--------------------------------------------------
    
    	#include<string.h>
    	#include<algorithm>
    	long long *Tree; // basic val
    	long long *add; // basic val
    
    // basic items--------------------------------------------------
    
    // user functions----------------------------------------------------------
    
    	long long seted_single = /* val */;
    	long long max_len = /* val */; /* val (times 4) */
    
    	void make_tree_basic_single(long long x) {
    		/* val */
    	}
    
    	void make_tree_basic_long(long long x) {
    		/* val */
    	}
    
    	inline 
    	long long make_tree_single(long long l, long long r) {
    		/* val */
    	}
    
    	inline 
    	long long make_tree_long(long long l, long long r) {
    		/* val */
    	}
    
    	void update_single(long long pos, long long val) {
    		/* val */
    	}
    
    	void update_long(long long pos, long long val) {
    		/* val */
    	}
    
    	inline 
    	long long comp_single(long long v1, long long v2) {
    		/* val */
    	}
    
    	inline 
    	long long comp_long(long long v1, long long v2)	{
    		/* val */
    	}
    
    // user functions------------------------------------------------------------
    
    	void init()	{
    		Tree = new long long[max_len * 4];
    		memset(Tree, 0, max_len * 4 * sizeof(long long));
    		add = new long long[max_len * 4];
    		memset(add, 0, max_len * 4 * sizeof(long long));
    	}
    
    	void build_single(long long l, long long r, long long k) {
    		if (l == r)	{
    			make_tree_basic_single(k);
    			return;
    		}
    
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		build_single(l, mid, ls);
    		build_single(mid + 1, r, rs);
    		Tree[k] = make_tree_single(ls, rs);
    	}
    
    	void build_long(long long l, long long r, long long k) {
    		if (l == r)	{
    			make_tree_basic_long(k);
    			return;
    		}
    
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		build_long(l, mid, ls);
    		build_long(mid + 1, r, rs);
    		Tree[k] = make_tree_long(ls, rs);
    	}
    
    	void single_update(long long l, long long r, long long k, long long place, long long val) {
    		if (l == r)	{
    			update_single(k, val);
    			return;
    		}
    
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		if (place <= mid) single_update(l, mid, ls, place, val);
    		else single_update(mid + 1, r, rs, place, val);
    		Tree[k] = make_tree_single(ls, rs);
    	}
    
    	void long_update(long long l, long long r, long long k, long long a, long long b, long long val) {
    		if(l >= a && r <= b) {
    			update_long(k, val);
    			return;
    		}
    
    		Tree[k] += (min(r, b) - max(l, a) + 1) * val;
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		if (a <= mid) long_update(l, mid, ls, a, b, val);
    		if (b > mid) long_update(mid + 1, r, rs, a, b, val);
    	}
    
    	inline 
    	long long long_query_single(long long l, long long r, long long k, long long a, long long b) {
    		if (a <= l && b >= r) return Tree[k];
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		long long tmp1 = seted_single, tmp2 = seted_single;
    		if (a <= mid) tmp1 = long_query_single(l, mid, ls, a, b);
    		if (b > mid) tmp2 = long_query_single(mid + 1, r, rs, a, b);
    		return comp_single(tmp1, tmp2);
    	}
    
    	inline 
    	long long long_query_long(long long l, long long r, long long k, long long a, long long b) {
    		if(l >= a && r <= b) return Tree[k] + (r - l + 1) * add[k];
    		long long mid = (l + r) >> 1;
    		long long ls = k << 1, rs = k << 1|1;
    		long long tmp = (min(r, b) - max(l, a) + 1) * add[k];
    		if (a <= mid) tmp += long_query_long(l, mid, ls, a, b);
    		if (b > mid) tmp += long_query_long(mid + 1, r, rs, a, b);
    		return tmp;
    	}
    };
    
    
  • 相关阅读:
    Hash大法
    最小表示法
    KMP算法题集
    分块总结
    2018 雅礼国庆集训
    二分图总结
    贪心总结
    Tire树总结(模板+例题)
    工具类文章合集
    网文胡乱汇总
  • 原文地址:https://www.cnblogs.com/zhangtianli/p/11625326.html
Copyright © 2020-2023  润新知