用pb_ds写一颗线段树

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/branch_policy/branch_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<class T1,class T2>
pair<T1,T2> operator +(const pair<T1,T2> &a,const pair<T1,T2> &b){
	return pair<T1,T2>(a.first+b.first,a.second+b.second);
}
#define TTT template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn, typename _Alloc>

TTT class interval_sum_node_update : detail::branch_policy<Node_CItr, Node_Itr, _Alloc>
{
	private:
		typedef detail::branch_policy<Node_CItr, Node_Itr, _Alloc> base_type;
	public:
		typedef Cmp_Fn 									cmp_fn;
		typedef _Alloc 									allocator_type;
		typedef typename allocator_type::size_type 		size_type;
		typedef typename base_type::key_type 			key_type;
		typedef typename base_type::key_const_reference	key_const_reference;
		typedef typename tuple_element<0,key_type>::type key_type_0;
		typedef typename tuple_element<1,key_type>::type key_type_1;
		typedef const key_type_0& key_0_const_reference;
		typedef const key_type_1& key_1_const_reference;
		
		typedef key_type 									metadata_type;
		typedef Node_CItr 	       							node_const_iterator;
		typedef Node_Itr 									node_iterator;
		typedef typename node_const_iterator::value_type 	const_iterator;
		typedef typename node_iterator::value_type 			iterator;
		
		key_type_1
		interval_sum(key_0_const_reference, key_0_const_reference);

	private:
		typedef typename base_type::const_reference 	const_reference;
		typedef typename base_type::const_pointer 		const_pointer;

		typedef typename _Alloc::template rebind<metadata_type>::other __rebind_m;
		typedef typename __rebind_m::const_reference       metadata_const_reference;
		typedef typename __rebind_m::reference 		metadata_reference;

		virtual node_const_iterator
		node_begin() const = 0;

		virtual node_iterator
		node_begin() = 0;

		virtual node_const_iterator
		node_end() const = 0;

		virtual node_iterator
		node_end() = 0;

		virtual cmp_fn&
		get_cmp_fn() = 0;
		
		key_type_1
		prefix_sum(key_const_reference);
	
		static const key_type_1 SUP=INT_MAX,INF=INT_MIN;
	
	protected:
		inline void
		operator()(node_iterator, node_const_iterator) const;
};

#define BELONG interval_sum_node_update<Node_CItr, Node_Itr, Cmp_Fn, _Alloc>

TTT
void BELONG::
operator ()(node_iterator cur, node_const_iterator end) const
{
	node_iterator l = cur.get_l_child(), r = cur.get_r_child();
	key_type_1 sl = l == end ? 0 : l.get_metadata().second,
		sr = r == end ? 0 : r.get_metadata().second;
	const_cast<metadata_reference>(cur.get_metadata()) = **cur + key_type(0,sl) + key_type(0,sr);
}

TTT
typename BELONG::key_type_1 BELONG::
prefix_sum(key_const_reference key)
{
	key_type_1 ret = 0;
	cmp_fn C = get_cmp_fn();
	node_iterator i = node_begin();
	for(node_iterator l, r; i != node_end(); )
	{
		l = i.get_l_child(), r = i.get_r_child();
		if(C(key, **i)) i = l;
		else
		{
			ret += (**i).second;
			if(l != node_end()) ret += l.get_metadata().second;
			i = r;
		}
	}
	return ret;
}

TTT
typename BELONG::key_type_1 BELONG::
interval_sum(key_0_const_reference l, key_0_const_reference r)
{
	return prefix_sum(make_pair(r,SUP)) - prefix_sum(make_pair(l,INF));
}

int main()
{
	tree<pair<int,int>, null_type, less<pair<int,int> >, splay_tree_tag, interval_sum_node_update> tr;
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		int t,tt;
		scanf("%d%d", &t,&tt);
		tr.insert(make_pair(t,tt));
	}
	printf("%d\n", tr.interval_sum(1, n));
}

注意typedef模板类时typename要记得加,参考自> https://www.cnblogs.com/js2xxx/p/9446963.html
tuple_element推断pair类型
程序中有人为设定的INT_MAX和INT_MIN

试用一下pb_ds的map

#include <iostream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/branch_policy/branch_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

int main()
{
	tree<int, int, less<int>, splay_tree_tag, tree_order_statistics_node_update> tr;
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		int t,tt;
		scanf("%d%d", &t,&tt);
		tr[t]=tt;
	}
	printf("%d\n", tr[1]);
}
posted @ 2020-12-01 22:54  Yuhuger  阅读(467)  评论(0编辑  收藏  举报