BZOJ 3772 精神污染 可持久化线段树

博客讲述了如何使用可持久化线段树解决BZOJ 3772题目的树上路径概率问题。通过维护树的入栈出栈序,将路径拆分为两段,并处理lca节点的重复计数,最终计算路径A包含于路径B的概率。
摘要由CSDN通过智能技术生成

题目大意:给定一棵树和树上的m条路径,求这m条路径中任选两条不同的路径时其中一条包含另一条的概率是多少

这题还真是精神污染- -

首先一个显而易见的结论就是如果路径A包含于路径B 那么就有A的两端点在路径B上 这是个充要条件

于是我们对于每个A路径的两段点x和y,将x开一个vector,把y存进去

这样对于每个B路径 我们要找的就是B路径上的所有点在vector中有多少出边也在这条B路径上

有些拗口- -

那么我们可以维护树上主席树来确定B链对应的线段树

我们要确定的就是B链对应的线段树中有多少点在B链上

那么维护入栈出栈序就可以了

将每个点维护一个可持久化线段树 版本是父亲版本加上该节点的vector中所有元素在入栈出栈序上的位置

由于是入栈出栈序 因此入栈为1 出栈为-1

由于入栈出栈序只能查询一个节点指向根的一条链 因此我们将[x,y]这条链拆成[x,lca]和[lca,y]两段

这其中由于lca被算了两次 因此还要减掉[lca,lca] 就可以了

注意自己对自己的影响不计入答案

- -卡内存差评

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;

struct Segtree{
	Segtree *ls,*rs;
	int val;
	void* operator new (size_t,Segtree *_,Segtree *__,int ___)
	{
		static Segtree mempool[3804000],*C=mempool;
		C->ls=_;
		C->rs&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值