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.pswp.cn/news/389261.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389261.shtml
英文地址,請注明出處:http://en.pswp.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&#…