1. 程式人生 > >[Noip2016]天天愛跑步 LCA+樹上差分

[Noip2016]天天愛跑步 LCA+樹上差分

—————————————-

概述

題目大意如下:

給定一棵n個點的樹,每一個點有一個點權w[i],再告訴你m條路徑的起點u和終點v。對於一條路徑,假如路徑上某一點x到起點u的距離等於w[x],那麼x的貢獻加1。最後求每一個點的貢獻。(1n,m300000,0w[i]n.)

—————————————-

分析

我當時考試的時候,看到這題第一眼感覺就是十分不可做,所以打了60分暴力草草了事。即使到現在,我仍感覺這道題絕對不是Noip的難度,畢竟涉及的演算法思想不是很容易就能想到,應該有Noi的級別。

言歸正傳,我們觀察一下這題。

根據套路,我們設1號節點為根,預處理出每一條路徑u,vl

ca,這裡我用的是樹鏈剖分。(因不會tarjon而瑟瑟發抖)

可以發現,假如我們的思路總是跟著“路徑上的每一個點能獲得的貢獻”去想,複雜度怎麼都是O(nm),不會有優化的空間。所以我們可以避開考慮每一條路徑能為路徑上的點所提供的貢獻,而是考慮每一個點如何能從路徑上獲得貢獻。

我們對每個點x這麼考慮:對x能產生貢獻的起點u一定與x的距離為w[x],我們設dep[i]i的深度,那麼u的位置可以分為兩種情況:

  1. ux深度大,即ux下方。

    此時有:

    dep[x]+w[x]=dep[u].

    我們能夠發現等式左邊的值只跟x有關,確定了x就確定了整個等式。

    那麼對x“可能”有貢獻的起點u即是在x

    的子樹中,且深度為dep[x]+w[x]的起點。

    注意一下,上文我說“可能”有貢獻,是因為以這個u為起點的路徑可能不會經過x,也就是說:uvlca可能在x的下方,即dep[lca]>dep[x]。這個情況我們在後面再考慮如何消除。

    我們建一個桶cnt[i]表示處理到當前時深度為i的起點的個數。那如何獲得在x的子樹中深度為dep[x]+w[x]的起點的個數呢?

    dep[x]+w[x]=t[x],我們可以發現,假如我們把初次搜尋到x時的cnt[t[x]]記錄下來,等搜尋完x的子樹後回溯到x時,此時新的cnt[[x]]與初次的cnt[t[x]]的差值即是x子樹中深度為t[x]的起點個數。

    好了,統計的問題我們解決了,那麼上面所提到的不應該有的貢獻如何消除呢?

    我們思考一下,假如ux的子樹內,lca若在x的子樹外則能保證這條路徑一定經過x,能對x產生貢獻,相反地,lca若在x的子樹內則沒有貢獻。

    所以,當我們處理完x這個點時,我們可以把所有lcax的路徑的貢獻刪除,這樣回溯到上面的時候就可以把本不應該有的貢獻消除了。

    第一種情況討論完畢。

  2. u的深度比x小,ux上方。

    這個時候起點u不在x的子樹裡,沒有辦法統計,所以我們可以換過來統計終點v的貢獻。

    此時有:

    dep[x]w[x]=dep[v]dis(u,v).

    我們觀察到等式左邊仍是隻與x有關的量,確定了x就能確定哪些終點對它有貢獻。

    類比第一種情況,我們另開一個桶cnt2[i]統計處理到當前點時,

    相關推薦

    NOIP2016天天跑步——LCA+樹上

    Description 小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 N個結點和N-1 條邊的樹, 每條邊連線兩個結點,且任意兩個結點存

    [Noip2016]天天跑步 LCA+樹上

    —————————————- 概述 題目大意如下: 給定一棵n個點的樹,每一個點有一個點權w[i],再告訴你m條路徑的起點u和終點v。對於一條路徑,假如路徑上某一點x到起點u的距離等於w[x],那麼x的貢獻加1。最後求每一個點的貢獻。(1≤n,m≤30

    [luogu1600 noip2016] 天天跑步樹上

    分享圖片 etc tdi 制作 name cout gist clas 輸出 題目描述 小c同學認為跑步非常有趣,於是決定制作一款叫做《天天愛跑步》的遊戲。《天天愛跑步》是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。 這個遊戲的地圖可以看作一一棵包含 n個結點和 n

    2018.11.09【NOIP2016】【洛谷P1600】天天跑步樹上

    傳送門 解析: 據說這是NOIP歷年最難一道題。。但是真的沒有寶藏難啊我覺得。。。 思路: 答案分兩類統計,一種是子樹中過來,一種是其他地方過來。那麼路徑就被拆分成兩部分了,一部分是S−>lcaS->lcaS−>lca,一部分

    「洛谷1600」「NOIP2016提高組」天天跑步樹上

    題目 給定 nod new nlogn 否則 top class 分享圖片 閑話 為了理清這道題目的思路,我是邊寫博客邊做題的,qwq。 題目鏈接 洛谷 題解 首先對變量進行聲明 dep[i] 表示i號節點的深度,是到根節點的深度 w[i] 表示i號觀測點觀測的時間

    NOIP2016提高組T2】天天跑步-倍增LCA+樹上

    測試地址:天天愛跑步 做法:這裡轉載一下我看的題解:點這裡,這裡面對於整個題的做法應該寫的很明確了,這裡就不再贅述了。我的做法是實時用倍增求出路徑兩點的LCA(當然也可以離線用Tarjan做,貌似快一點),然後用類似鄰接表的連結串列結構儲存上面題解裡面的“人”,結構體裡有四

    bzoj4719 [Noip2016]天天跑步(樹+lca+樹上+思路題)

    進入bzoj法眼的noip(lus)題hh。題解太麻煩啦。。。不寫啦。。。就體會一下思想:要是對於每條路徑操作,看他會影響哪些點的貢獻,鐵鐵的會t。所以考慮怎樣的一條路徑會對一個點產生貢獻,先討論簡化版的鏈的情況,發現要討論左右。結合另外兩個部分分,感覺就是把路

    NOIP2016 天天跑步LCA樹上

    Description 小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。«天天愛跑步»是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。 這個遊戲的地圖可以看作一一棵包含n個結點和n−1條邊的樹, 每條邊連線兩個結點,且任意兩個結點存

    LCA+樹上天天跑步

    blog 分支 div fin out 答案 簡單 printf 但是 困擾我半年多的題終於做出來了 一開始我的做法是想在回溯的時候統計答案,但是各個分支之間又會相互影響,然後就不會做了 看完別人的題解後發現用桶的前後狀態做差來統計答案更簡單 1 #include &l

    [Noip2016]天天跑步 樹上

    stact 0ms 情況下 類型 輸出 記錄 一行 push pri $ \rightarrow $ 戳我進洛谷原題** $ \rightarrow $ 戳我進BZOJ原題** 天天愛跑步   時空限制 \quad 2000ms / 512MB 題目描述 小c同學認為跑步非

    NOIP2016 天天跑步 (樹上+dfs)

    產生 using cto continue 有一個 swa http get bug 題目大意:給你一顆樹,樹上每個點都有一個觀察員,他們僅會在 w[i] 時刻出現,觀察正在跑步的玩家 一共有m個玩家,他們分別從節點 s[i] 同時出發,以每秒跑一條邊的速度,沿著到 t[i

    bzoj4719: [Noip2016]天天跑步 樹上

    -a 用兩個 output 玩家 name cst while con bzoj Description 小c同學認為跑步非常有趣,於是決定制作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是一個養成類遊戲,需要 玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包

    【NIOIP2016提高】天天跑步LCA+樹上

    近幾年複賽最難的樹上問題了。 幾個月前做是參照題解的方法,用了可持久化線段樹在樹上無腦維護和統計。 當時的做法早已忘記,於是回過來自己做了做,其實遠沒有那麼難做,只要發現一些奇妙的性質。 對於一個玩家s->t,如圖。 對於圖中a點的觀察員存在這樣一個式子

    NOIP2016 day1T2--BZOJ4719 天天跑步--LCA+

    Description 小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是一個養成類遊戲,需要 玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 N個結點和N-1 條邊的樹, 每條邊連線兩 個結點,且任意兩

    NOIP2016天天跑步 題解報告【lca+樹上統計(桶)】

    題目描述 小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。«天天愛跑步»是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。 這個遊戲的地圖可以看作一一棵包含 nn個結點和 n-1n−1條邊的樹, 每條邊連線兩個結點,且任意兩個結點存在一條

    LCA+線段樹 NOIP2016 天天跑步

    art swa 單獨 編譯 如果 建立 const 會有 void 天天愛跑步 題目描述 小c同學認為跑步非常有趣,於是決定制作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是一個養成類遊戲,需要玩家每天按時上線,完成打卡任務。 這個遊戲的地圖可以看作一一棵包含 nnn個結

    [bzoj4719][樹鏈剖][Noip2016]天天跑步

    4719: [Noip2016]天天愛跑步 Time Limit: 40 Sec Memory Limit: 512 MB Submit: 1022 Solved: 342 [Submit][Status][Discuss] Description

    [樹鏈剖+線段樹] bzoj4719: [Noip2016]天天跑步【留坑待填】

    從s到t 上升時,對於經過的每一個節點i 設經過了t[i]條路徑 即用時t[i] t[i]=dep[s]-dep[i] 得t[i]+dep[i]=dep[s] 同樣 下降時,對於每一個經過的節點i t[i]=(dep[i]-dep[lc

    noip2016 天天跑步

    ini node 右移 += upd 時間 個人 方法 最短路 分析:這道題真心煩啊,是我做過noip真題中難度最高的一道了,到今天為止才把noip2016的坑給填滿.暴力的話前60分應該是可以拿滿的,後40分還是很有難度的. 定義:每個人的起點、終點:s,t;深度

    [luogu]P1600 天天跑步[LCA]

    == 同學 問題 i++ mil com get new sin [luogu]P1600 [NOIP 2016]天天愛跑步 題目描述 小c同學認為跑步非常有趣,於是決定制作一款叫做《天天愛跑步》的遊戲。«天天愛跑步»是一個養成類遊戲,需要玩家