【好題】洛谷 P1600 [NOIP 2016 提高組] 天天愛跑步(倍增LCA+桶)

前言

沒做出來,看了很多篇題解后AC了,感覺大部分題解講得不清楚。

題目

思路

結果有兩種求法

  1. 模擬跑步過程,統計每個節點能觀察到的人數
  2. 考慮每條路徑會對哪些節點作出貢獻(當前路徑的玩家能被觀察到)

嘗試

第一種求法必須遍歷當前路徑的所有節點,不能優化,因為不能跳過任何節點,最壞時間復雜度O(nm),超時,換思路。

正解思路

不再遍歷統計,換第二種求法。

路徑 si → ti 若能對節點 u 有貢獻,節點u一定是路徑L上的節點。

分情況討論

  1. 節點u在路徑 si → lca(si, ti) 上,設depth[i] = 節點i的深度(根節點為1),此時depth[si] = depth[u] + w[u]。
  2. 節點u在路徑 lca(si, ti)?→ ti 上,設dis(x, y) = x到y之間的距離,此時 dis(si, ti) = w[u] + (depth[ti] - depth[u]),移項得 dis(si, ti) - depth[ti] = w[u] - depth[u],移項后等式左邊是已知量。

根據等式,且n < 10^6,用桶快速得出節點觀察到的人數,設 cntStart[depth[u] + w[u]] = 滿足節點 u 的 si(即depth[si]?= depth[u] + w[u]),起點為 si 的路徑個數;cntLast[w[u] - depth[u]] = 滿足節點 u 的 ti,(即dis(si, ti) - depth[ti] = w[u] - depth[u]),終點為ti的路徑個數。

設result[u] = 在節點u能觀察到的人數(相當于路徑數)。

除了節點 u = lca(si, ti) 的情況,節點u要么在路徑 si → lca(si, ti) 上,此時 result[u] +=?起點為 si 的路徑個數,要么在路徑 lca(si, ti)?→ ti 上,此時 result[u] += 終點為ti的路徑個數,路徑個數正確統計。

當節點 u = lca(si, ti),若 si 和 ti 會對節點u產生貢獻,此時 result[u] +=?起點為 si 的路徑個數 +?終點為ti的路徑個數,si → ti 的路徑會被計算兩次(si 計算一次,ti 計算一次),需要result[u] = result[u] - 1。

當路徑?si → ti 的 si 滿足?depth[si] = depth[lca(si, ti)] + w[lca(si, ti)],ti也會滿足dis(si, ti) - depth[ti] = w[lca(si, ti)] - depth[lca(si, ti)]。

證明

depth[lca(si, ti)] + w[lca(si, ti)] = w[lca(si, ti)] - depth[lca(si, ti)] + 2 ×?depth[lca(si, ti)],

那么有

dis(si, ti) - depth[ti] +?2 ×?depth[lca(si, ti)]?= w[lca(si, ti)] - depth[lca(si, ti)] +?2 ×?depth[lca(si, ti)],化簡得

depth[si] = depth[lca(si, ti)] + w[lca(si, ti)] 。

證畢

所以只要判斷到 depth[si] = depth[lca(si, ti)] + w[lca(si, ti)] ,就result[lca(si, ti)] = result[lca(si, ti)] - 1。

實現

發現無論什么情況,si、ti 都在以節點u為根的子樹上,所以 dfs 遍歷,回溯的時候統計。

tot1 = 以節點u為根的子樹之外的起點 si 滿足 depth[si] = depth[u] + w[u] 的路徑個數,tot2 =?以節點u為根的子樹之外的終點 ti?滿足 dis(si, ti) - depth[ti] = w[u] - depth[u] 的路徑個數,計算tot1,tot2是為了去掉節點u不再上面的路徑數。根據 tot1 和 tot2 的定義,要在下一層遞歸前求解。

先統計節點u為起點和為終點時有貢獻的路徑數,可能滿足?depth[si] = depth[u] + w[u] 的 si 為 u,滿足?dis(si, ti) - depth[ti] = w[u] - depth[u] 的 ti 為 u。

最后減去 lca(si, ti) = u 的路徑數,這些路徑之后不會再被計入。

LCA用倍增加速求解。

細節見代碼。

代碼

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;typedef long long LL;const LL Maxn = 299998 + 5;
const LL Maxm = 299998 + 5;
const LL Maxk = 20;
const LL Size = 300000;struct node {LL s, t, e;
} pla[Maxm];vector<LL> tree[Maxn];
vector<LL> tId[Maxn];
vector<LL> LId[Maxn];
LL vct_w[Maxn], depth[Maxn], father[Maxn][Maxk];
LL cnt_s[Maxn], cntStart[Maxn * 2], cntLast[Maxn * 2], result[Maxn];void init(LL u, LL fa) {depth[u] = depth[fa] + 1;father[u][0] = fa;for (LL i = 1; depth[u] > (1 << i); ++i) {father[u][i] = father[father[u][i - 1]][i - 1];}for (auto v : tree[u]) {if (v != fa)  init(v, u);}return;
}LL LCA(LL u, LL v) {if (depth[u] < depth[v])  swap(u, v);for (LL i = Maxk - 1; i >= 0; --i) {if (depth[father[u][i]] >= depth[v])  u = father[u][i];}if (u == v)  return u;for (LL i = Maxk - 1; i >= 0; --i) {if (father[u][i] != father[v][i]) {u = father[u][i];v = father[v][i];}}return father[u][0];
}void dfs(LL u, LL fa) {LL tot1 = cntStart[depth[u] + vct_w[u]], tot2 = cntLast[vct_w[u] - depth[u] + Size];for (auto v : tree[u]) {if (v != fa)  dfs(v, u);}cntStart[depth[u]] += cnt_s[u];for (auto id : tId[u]) {++cntLast[pla[id].e - depth[pla[id].t] + Size];}result[u] += (cntStart[depth[u] + vct_w[u]] - tot1) + (cntLast[vct_w[u] - depth[u] + Size] - tot2);for (auto id : LId[u]) {--cntStart[depth[pla[id].s]];--cntLast[pla[id].e - depth[pla[id].t] + Size];}return;
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);LL n, m, u, v;cin >> n >> m;for (LL i = 1; i < n; ++i) {cin >> u >> v;tree[u].emplace_back(v);tree[v].emplace_back(u);}for (LL i = 1; i <= n; ++i)  cin >> vct_w[i];init(1, 0);LL lcaId = 0;for (LL i = 1; i <= m; ++i) {cin >> pla[i].s >> pla[i].t;lcaId = LCA(pla[i].s, pla[i].t);pla[i].e = depth[pla[i].s] + depth[pla[i].t] - depth[lcaId] * 2;++cnt_s[pla[i].s];tId[pla[i].t].emplace_back(i);LId[lcaId].emplace_back(i);if (depth[pla[i].s] == depth[lcaId] + vct_w[lcaId])  --result[lcaId];}dfs(1, 0);for (LL i = 1; i <= n; ++i)  cout << result[i] << ' ';return 0;
}

注意

  • cntStart要開到2 * Maxn
  • 明確每個數組的下標和元素是什么,搞錯很難調
  • 思路是一條條的路徑,被卡住就換條路徑。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89782.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89782.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

valkey之網絡管理架構深度解析

一、連接類型實現體系 valkey通過ConnectionType結構體構建了靈活的網絡連接抽象&#xff0c;支持多種連接類型的統一管理。每種連接類型都通過填充該結構體的函數指針來實現特定功能&#xff0c;形成了面向接口的設計模式。1.1 socket連接 Socket連接提供了最基礎的TCP/IP通信…

【解碼文本世界的“隱形分界線”:Windows與Linux回車換行之謎】

在計算機的文本世界里&#xff0c;回車&#xff08;Carriage Return&#xff0c;CR&#xff09;和換行&#xff08;Line Feed&#xff0c;LF&#xff09;是兩個看似簡單卻意義非凡的字符。它們如同文本中的“隱形分界線”&#xff0c;默默地劃分著段落與行&#xff0c;影響著文…

【Project】ELK 7.17.16 日志分析系統部署

ELK 日志分析系統集群部署 本文檔基于 Rocky Linux 9.4 系統&#xff0c;部署 ELK 7.17.16&#xff08;長期支持版&#xff09;集群 案例準備 1. 節點規劃IP主機名部署組件角色說明192.168.100.150kafka01Elasticsearch、Kibana主節點&#xff08;master&#xff09; 可視化192…

分布式定時任務系列13:死循環是任務觸發的銀彈?

傳送門 分布式定時任務系列1&#xff1a;XXL-job安裝 分布式定時任務系列2&#xff1a;XXL-job使用 分布式定時任務系列3&#xff1a;任務執行引擎設計 分布式定時任務系列4&#xff1a;任務執行引擎設計續 分布式定時任務系列5&#xff1a;XXL-job中blockingQueue的應用 …

Flutter基礎(前端教程①③-單例)

現實類比&#xff1a;公司打印機假設你們公司有一臺共享打印機&#xff1a;非單例&#xff08;重復創建&#xff09;&#xff1a;每個員工都自己買一臺打印機放在工位上結果&#xff1a;浪費錢&#xff0c;占空間&#xff0c;難維護單例&#xff08;唯一實例&#xff09;&#…

力扣刷題 -- 965.單值二叉樹

題目示例&#xff1a; 思路分析代碼實現 bool isUnivalTree(struct TreeNode* root) {if(rootNULL){return true;}if(root->left && root->val ! root->left->val){return false;}if(root->right && root->val ! root->right->val){re…

uni-api交互反饋組件(showToast)的用法

歡迎來到我的UniApp技術專欄&#xff01;&#x1f389; 在這里&#xff0c;我將與大家分享關于UniApp開發的實用技巧、最佳實踐和項目經驗。 專欄特色&#xff1a; &#x1f4f1; 跨平臺開發一站式解決方案 &#x1f680; 從入門到精通的完整學習路徑 &#x1f4a1; 實戰項目經…

借助它,在Web3投資賽道搶占先機

隨著互聯網技術的飛速發展&#xff0c;Web3的概念逐漸成為科技圈和投資界的熱門話題。Web3代表著下一代互聯網的發展方向&#xff0c;它強調去中心化、用戶主權和數據隱私保護。在這一新興領域&#xff0c;如何借助Web3技術搶占投資先機&#xff0c;成為許多投資者關注的焦點。…

驗證大語言模型不會算數但可以編寫算數的程序

摘要&#xff1a;本文通過幾個實例測試了大語言模型在數學計算、排序、統計等方面的能力。結果顯示&#xff0c;對于簡單字符統計、排序等任務&#xff0c;大模型能正確生成實現代碼&#xff0c;但當數據區分度降低時容易出錯。在計算學生分數排名任務中&#xff0c;大模型生成…

概率論與數理統計(八)

參數估計 通過取樣本&#xff0c;并用樣本構造函數&#xff0c;達成估計分布函數參數的目的 矩估計法 本質&#xff1a;用樣本的各階矩代替總體的各階矩&#xff0c;即取&#xff1a; E(X)X ̄1n∑iXiE(X2)1n∑iXi2E(X)\overline{X}\dfrac{1}{n}\sum_i X_i\\ E(X^2)\dfrac{1}…

服務器后臺崩潰的原因

當我們雙十一活動零點拼命刷新卻卡在支付完頁面&#xff0c;游戲頁面等不進去&#xff0c;公司系統癱瘓全體員工干瞪眼&#xff0c;服務器崩潰絕對是數字時代中的酷刑&#xff01;那服務器為什么會說崩就崩&#xff0c;用戶對于這種情況該如何進行避雷呢&#xff1f;服務器主要…

線程池與ThreadPoolExecutor源碼解析(上)

一、線程池線程池&#xff08;ThreadPool&#xff09;是一種線程復用的機制。它維護著若干個線程&#xff0c;任務來了就復用這些線程去執行&#xff0c;任務做完線程不會銷毀&#xff0c;而是回到池中等待下一個任務。為什么要用線程池&#xff1f;降低資源消耗&#xff1a;避…

Linux內核IP分片重組機制剖析:高效與安全的藝術

在IP網絡通信中,當數據包超過MTU限制時,路由器會將其拆分為多個分片。這些分片到達目標主機后,內核必須高效、安全地重組原始數據包。Linux內核的net/ipv4/inet_fragment.c實現了一套精妙的分片管理框架,完美平衡了性能和安全性需求。本文將深入剖析其設計哲學與關鍵技術。…

相機模型和對極幾何

一、相機模型 1.針孔相機模型-外參矩陣 1.世界坐標系到相機坐標系 世界坐標系&#xff1a;可以定義空間中任意一個位置&#xff0c;原點位置三個坐標軸方向坐標系姿態&#xff08;X,Y,Z&#xff09;相機坐標系&#xff1a;定義在相機上&#xff0c;原點是相機中心&#xff0c;z…

Git 常用命令與操作步驟

以下是 Git 常用命令與操作步驟 的整理&#xff0c;涵蓋日常開發中最核心的場景&#xff0c;適合快速查閱和上手&#xff1a;1. 初始化與克隆倉庫操作命令本地初始化倉庫git init克隆遠程倉庫git clone <倉庫URL> &#xff08;如 git clone https://gitlab.com/user/repo…

Leetcode-.283移動零

class Solution:def moveZeroes(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""pos0for i in range(len(nums)):if nums[i]!0:nums[pos],nums[i]nums[i],nums[pos]pos1本題運用雙指針來寫&…

在React中做過哪些性能優化?

1. 使用 React.memo 進行組件優化 問題:當父組件重新渲染時,子組件也會重新渲染,即使它的 props 沒有變化。 解決方案:使用 React.memo 包裹子組件,讓其只在 props 變化時才重新渲染。 const MyComponent = React.memo((props) => {// 子組件代碼 }); 2. 使用 useCa…

安裝docker可視化工具 Portainer中文版(ubuntu上演示,所有docker通用) 支持控制各種容器,容器操作簡單化 降低容器門檻

以下有免費的4090云主機提供ubuntu22.04系統的其他入門實踐操作 地址&#xff1a;星宇科技 | GPU服務器 高性能云主機 云服務器-登錄 相關兌換碼星宇社區---4090算力卡免費體驗、共享開發社區-CSDN博客 兌換碼要是過期了&#xff0c;可以私信我獲取最新兌換碼&#xff01;&a…

ansible批量部署zabbix客戶端

?ansible編寫劇本步驟 1??創建roles目錄結構2??在group_vars/all/main.yml中定義變量列表3??在tasks目錄下編寫tasks任務4??在files目錄下準備部署文件5??在templates目錄下創建j2模板文件6??在handlers目錄下編寫handlers7??在roles目錄下編寫主playbook8??運…

螞蟻數科AI數據產業基地正式投產,攜手蘇州推進AI產業落地

近日&#xff0c;螞蟻數科AI數據產業基地在太倉智匯谷科技創新園正式投產。該基地作為蘇州市首個AI數據產業基地&#xff0c;旨在通過跨行業人才與前沿技術&#xff0c;為長三角制造業、金融、醫療等領域的大模型落地提供場景化、高質量的訓練數據支撐。數據被視為AI學習的核心…