BZOJ 3653: 谈笑风生(离线, 长链剖分, 后缀和)

题意

给你一颗有 \(n\) 个点并且以 \(1\) 为根的树。共有 \(q\) 次询问,每次询问两个参数 \(p, k\) 。询问有多少对点 \((p, a, b)\) 满足 \(p,a,b\) 为三个不同的点,\(p, a\) 都为 \(b\) 的祖先,且 \(p\)\(a\) 的距离不能超过 \(k\)

\(n\le 300000 , q\le 300000\) 不要求强制在线。

题解

\(dep[u]\) 为点 \(u\) 的深度,\(sz[u]\)\(u\) 的子树大小(除去 \(u\) 本身)

首先我们考虑两种情况:

  1. \(a\)\(p\) 的祖先,那么这部分贡献很好计算,就是 \(\min\{dep[p] - 1,k\} \times sz[u]\)
  2. \(a\)\(p\) 的子树内,那么这部分贡献就是 \(\displaystyle \sum_{dis(p,a) \le k} sz[a]\)

我们现在只要考虑第二部分贡献怎么求。

不难发现,这些点的深度就是 \([dep[p], dep[p]+k]\) 这个范围内的。

那么我们可以对于每个点用个 主席树 来存储这些信息,可以在线回答询问。

那么离线的话,可以考虑用 线段树合并 维护它每个子树的信息。

具体来说,这些都是对于每个 \(dep\) 维护它的 \(sz\) 的和,然后查区间和就行了。

然而这些时空复杂度都是 \(O(n \log n)\) ,其实还有更好的做法。

为什么我发现了呢qwq?

因为 fatesky 做这道题线段树合并做法的时候,Wearry 说可以 长链剖分 那就是 \(O(n)\) 的啦。

我们令 \(\displaystyle maxdep[u]=\max_{v \in child[u]} \{dep[v\}\) 也就是它子树中的最大深度。

具体来说,长链剖分就是把每个点儿子中 \(maxdep\) 最大的那个当做重儿子。重儿子与父亲连的边叫做重边。一连串重边不间断连到一起就叫做重链。

然后我们就有一条性质。

性质1 : 重链长度之和是 \(O(n)\) 的。

这个很显然啦,因为总共只有 \(O(n)\) 级别的边。

有了这个我们就可以解决一系列 关于深度的动态规划 问题了,对于这列问题常常都可以做到 \(O(n)\) 的复杂度。

具体操作就是,每次暴力继承重儿子的 \(dp\) 状态,然后轻儿子暴力合并上去。

不难发现这个复杂度是 \(O(\sum\) 重链长 \()\) \(= O(n)\) 的。

继承的时候常常需要移位,并且把当前节点贡献算入,并且这个 \(dp\) 需要动态空间才能实现。

对于这道题我们考虑维护一个后缀和,也就是对于 \(u\) 子树中的 \(v\)\(dep[v] \ge k\) 的所有 \(sz[v]\) 的和。

不难发现后缀和是很好合并的,这个的复杂度只需要 \(O(\min maxdep[v])\)

每次添加一个点 \(sz[u]\) 对于 \(dep[u]\) 的贡献只会对一个点的贡献产生影响,这个复杂度是 \(O(1)\) 的。

代码实现的话,就可以用一个 std :: vector ,按深度从大到小 ( \(maxdep[u] \to dep[u]\) )存储每个点的信息,因为这样最方便继承重儿子状态(每次加入状态只在整个 vector 末端添加一个元素)

其实可以动态开内存,顺着做,但我似乎学不来

常数似乎有点大,没比 \(O(n \log n)\) 快多少,vector 用多了... Wearry 到是优化了点常数到了 \(4000+ ms\)

话说这个很像原来 DOFY 讲过的那道 Dsu on Tree

代码

#include <bits/stdc++.h>#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)using namespace std;typedef long long ll;inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}inline int read() {int x = 0, fh = 1; char ch = getchar();for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);return x * fh;
}void File() {
#ifdef zjp_shadowfreopen ("3653.in", "r", stdin);freopen ("3653.out", "w", stdout);
#endif
}const int N = 3e5 + 1e3;struct Ask { int k, id; } ; vector<Ask> V[N];vector<int> G[N]; int sz[N], maxdep[N], dep[N], sonmaxdep[N], son[N], rt[N];vector<ll> sum[N]; int n, q; ll ans[N], Size = 0;void Dfs_Init(int u, int fa = 0) {maxdep[u] = dep[u] = dep[fa] + 1;For (i, 0, G[u].size() - 1) {register int v = G[u][i];if (v ^ fa) Dfs_Init(v, u), chkmax(maxdep[u], maxdep[v]);}}void Dfs(int u, int fa = 0) {For (i, 0, G[u].size() - 1) {int v = G[u][i];if (v == fa) continue ;Dfs(v, u); sz[u] += sz[v];if (maxdep[v] > maxdep[son[u]]) son[u] = v;}rt[u] = rt[son[u]]; if (!rt[u]) rt[u] = ++ Size;int len = (int)sum[rt[u]].size();ll Last = len ? sum[rt[u]][len - 1] : 0;sum[rt[u]].push_back(Last);if (son[u]) {For (i, 0, G[u].size() - 1) {int v = G[u][i]; if (v == fa || v == son[u]) continue ;For (j, 0, sum[rt[v]].size() - 1) {int nowdep = (maxdep[son[u]] - maxdep[v]) + j;sum[rt[u]][nowdep] += sum[rt[v]][j];}sum[rt[u]][len] += sum[rt[v]][sum[rt[v]].size() - 1];}}For (i, 0, V[u].size() - 1) {Ask now = V[u][i];ans[now.id] = sum[rt[u]][len];if (len > now.k) ans[now.id] -= sum[rt[u]][len - now.k - 1];ans[now.id] += 1ll * min(dep[u] - 1, now.k) * sz[u];}sum[rt[u]][len] += sz[u]; ++ sz[u];}int main () {File();n = read(); q = read();For (i, 1, n - 1) {int u = read(), v = read();G[u].push_back(v);G[v].push_back(u);}For (i, 1, q) {int p = read(), k = read();V[p].push_back((Ask) {k, i});}Dfs_Init(1); Dfs(1);For (i, 1, q)printf ("%lld\n", ans[i]);return 0;
}

转载于:https://www.cnblogs.com/zjp-shadow/p/9262234.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搜索引擎优化学习原理_如何使用数据科学原理来改善您的搜索引擎优化工作

搜索引擎优化学习原理Search Engine Optimisation (SEO) is the discipline of using knowledge gained around how search engines work to build websites and publish content that can be found on search engines by the right people at the right time.搜索引擎优化(SEO…

Siamese网络(孪生神经网络)详解

SiameseFCSiamese网络&#xff08;孪生神经网络&#xff09;本文参考文章&#xff1a;Siamese背景Siamese网络解决的问题要解决什么问题&#xff1f;用了什么方法解决&#xff1f;应用的场景&#xff1a;Siamese的创新Siamese的理论Siamese的损失函数——Contrastive Loss损失函…

Dubbo 源码分析 - 服务引用

1. 简介 在上一篇文章中&#xff0c;我详细的分析了服务导出的原理。本篇文章我们趁热打铁&#xff0c;继续分析服务引用的原理。在 Dubbo 中&#xff0c;我们可以通过两种方式引用远程服务。第一种是使用服务直联的方式引用服务&#xff0c;第二种方式是基于注册中心进行引用。…

期权价格的上限和下限

期权按照买方权利性质分为&#xff1a;看涨期权和看跌期权 1、首先&#xff0c;看涨期权的上限和下限 看涨期权价格上限为其标的资产价格。 看涨期权是给予买方一个在未来买入标的资产的权利&#xff0c;如果该权利的价格高于标的资产的价格&#xff0c;那么投资者不如直接购买…

一件登录facebook_我从Facebook的R教学中学到的6件事

一件登录facebookBetween 2018 to 2019, I worked at Facebook as a data scientist — during that time I was involved in developing and teaching a class for R beginners. This was a two-day course that was taught about once a month to a group of roughly 15–20 …

SiameseFC超详解

SiameseFC前言论文来源参考文章论文原理解读首先要知道什么是SOT&#xff1f;&#xff08;Siamese要做什么&#xff09;SiameseFC要解决什么问题&#xff1f;SiameseFC用了什么方法解决&#xff1f;SiameseFC网络效果如何&#xff1f;SiameseFC基本框架结构SiameseFC网络结构Si…

Python全栈工程师(字符串/序列)

ParisGabriel Python 入门基础字符串&#xff1a;str用来记录文本信息字符串的表示方式&#xff1a;在非注释中凡是用引号括起来的部分都是字符串‘’ 单引号“” 双引号 三单引""" """ 三双引有内容代表非空字符串否则是空字符串 区别&#xf…

跨库数据表的运算

跨库数据表的运算&#xff0c;一直都是一个说难不算太难&#xff0c;说简单却又不是很简单的、总之是一个麻烦的事。大量的、散布在不同数据库中的数据表们&#xff0c;明明感觉要把它们合并起来&#xff0c;再来个小小的计算&#xff0c;似乎也就那么回事……但真要做起来&…

FCN全卷积网络随笔

参考&#xff1a;四、全卷积网络FCN详细讲解&#xff08;超级详细哦&#xff09; 这篇文章已经写的很好了&#xff0c;这里说两个我考虑的点。 第一个就是&#xff1a;FCN在缩小成heat map&#xff0c;为什么要通过上采样还原回原图大小&#xff1f; 我觉得这个的原因是因为&a…

熊猫在线压缩图_回归图与熊猫和脾气暴躁

熊猫在线压缩图数据可视化 (Data Visualization) I like the plotting facilities that come with Pandas. Yes, there are many other plotting libraries such as Seaborn, Bokeh and Plotly but for most purposes, I am very happy with the simplicity of Pandas plotting…

敏捷数据科学pdf_敏捷数据科学数据科学可以并且应该是敏捷的

敏捷数据科学pdfTL;DR;TL; DR; I have encountered a lot of resistance in the data science community against agile methodology and specifically scrum framework; 在数据科学界&#xff0c;我遇到了许多反对敏捷方法论(特别是Scrum框架)的抵制。 I don’t see it this …

oracle的连接字符串

OracleConnection oCnn new OracleConnection("Data SourceORCL_SERVER;USERM70;PASSWORDmmm;");建立个角色 建立个表空间(角色与表空间同名的) 在方案里就可以建立表,然后就哦了 10g

SiameseRPN详解

SiameseRPN论文来源论文背景一&#xff0c;简介二&#xff0c;研究动机三、相关工作论文理论注意&#xff1a;网络结构&#xff1a;1.Siamese Network2.RPN3.LOSS计算4.Tracking论文的优缺点分析一、Siamese-RPN的贡献/优点&#xff1a;二、Siamese-RPN的缺点&#xff1a;代码流…

数据可视化 信息可视化_可视化数据操作数据可视化与纪录片的共同点

数据可视化 信息可视化Data visualization is a great way to celebrate our favorite pieces of art as well as reveal connections and ideas that were previously invisible. More importantly, it’s a fun way to connect things we love — visualizing data and kicki…

python 图表_使用Streamlit-Python将动画图表添加到仪表板

python 图表介绍 (Introduction) I have been thinking of trying out Streamlit for a while. So last weekend, I spent some time tinkering with it. If you have never heard of this tool before, it provides a very friendly way to create custom interactive Data we…

Python--day26--复习

转载于:https://www.cnblogs.com/xudj/p/9953293.html

sockets C#

Microsoft.Net Framework为应用程序访问Internet提供了分层的、可扩展的以及受管辖的网络服务&#xff0c;其名字空间System.Net和System.Net.Sockets包含丰富的类可以开发多种网络应用程序。.Net类采用的分层结构允许应用程序在不同的控制级别上访问网络&#xff0c;开发人员可…

667. Beautiful Arrangement II

找规律 1&#xff0c;2&#xff0c;... , n 乱序排列&#xff0c;相邻数据的绝对差最多有n-1种 比如1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5对应于 1 5 2 4 3 class Solution { public:vector<int> constructArray(int n, int k) {vector<int> re…

SiameseRPN++分析

SiamRPN论文来源论文背景什么是目标跟踪什么是孪生网络结构Siamese的局限解决的问题论文分析创新点一&#xff1a;空间感知策略创新点二&#xff1a;ResNet-50深层网络创新点三&#xff1a;多层特征融合创新点四&#xff1a;深层互相关代码分析整体代码简述&#xff08;1&#…