日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 4719: [Noip2016]天天爱跑步 线段树合并

發(fā)布時(shí)間:2024/1/1 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 4719: [Noip2016]天天爱跑步 线段树合并 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

title

BZOJ 4719

LUOGU 1600

簡(jiǎn)化題意:

小c同學(xué)認(rèn)為跑步非常有趣,于是決定制作一款叫做《天天愛(ài)跑步》的游戲。《天天愛(ài)跑步》是一個(gè)養(yǎng)成類(lèi)游戲,需要玩家每天按時(shí)上線,完成打卡任務(wù)。

這個(gè)游戲的地圖可以看作一一棵包含 \(n\) 個(gè)結(jié)點(diǎn)和 \(n-1\) 條邊的樹(shù), 每條邊連接兩個(gè)結(jié)點(diǎn),且任意兩個(gè)結(jié)點(diǎn)存在一條路徑互相可達(dá)。樹(shù)上結(jié)點(diǎn)編號(hào)為從 \(1\)\(n\) 的連續(xù)正整數(shù)。

現(xiàn)在有 \(m\) 個(gè)玩家,第 \(i\) 個(gè)玩家的起點(diǎn)為 \(S_i\) ,終點(diǎn)為 \(T_i\) 。每天打卡任務(wù)開(kāi)始時(shí),所有玩家在第 \(0\) 秒同時(shí)從自己的起點(diǎn)出發(fā),以每秒跑一條邊的速度,不間斷地沿著最短路徑向著自己的終點(diǎn)跑去,跑到終點(diǎn)后該玩家就算完成了打卡任務(wù)。 (由于地圖是一棵樹(shù),所以每個(gè)人的路徑是唯一的)

小c想知道游戲的活躍度,所以在每個(gè)結(jié)點(diǎn)上都放置了一個(gè)觀察員。 在結(jié)點(diǎn) \(j\) 的觀察員會(huì)選擇在第 \(W_j\) 秒觀察玩家,一個(gè)玩家能被這個(gè)觀察員觀察到當(dāng)且僅當(dāng)該玩家在第 \(W_j\) 秒也理到達(dá)了結(jié)點(diǎn) \(j\) 。 小C想知道每個(gè)觀察員會(huì)觀察到多少人?

注意:我們認(rèn)為一個(gè)玩家到達(dá)自己的終點(diǎn)后該玩家就會(huì)結(jié)束游戲,他不能等待一 段時(shí)間后再被觀察員觀察到。 即對(duì)于把結(jié)點(diǎn) \(j\) 作為終點(diǎn)的玩家:若他在第 \(W_j\) 秒前到達(dá)終點(diǎn),則在結(jié)點(diǎn) \(j\) 的觀察員不能觀察到該玩家;若他正好在第 \(W_j\) 秒到達(dá)終點(diǎn),則在結(jié)點(diǎn) \(j\) 的觀察員可以觀察到這個(gè)玩家。

analysis

對(duì)于一個(gè)人,他的路程會(huì)分為兩段,一段向上(根),一段向下,考慮在向上過(guò)程中他能產(chǎn)生貢獻(xiàn)的觀察者具有什么性質(zhì):設(shè)出發(fā)點(diǎn)深度為 \(dep[x]\),觀察者深度為 \(dep[y]\),觀察的時(shí)間為 \(t\),需滿(mǎn)足 \(dep[x]?dep[y]=t\),換句話說(shuō)就是 \(dep[y]+t=dep[x]\) 。向下那一段的推導(dǎo)類(lèi)似,下面的部分也只以向上的路徑為例來(lái)解釋。

現(xiàn)在我們記錄每個(gè)點(diǎn)下方出發(fā)點(diǎn)深度為 \(dep[x]\) 的人數(shù),需要對(duì)于每個(gè)出發(fā)點(diǎn)更新出發(fā)點(diǎn)到出發(fā)點(diǎn)與目的地的 \(lca\) 的所有點(diǎn),想到到開(kāi)一顆權(quán)值線段樹(shù),用線段樹(shù)合并不斷把信息往上傳,在 \(lca\) 處消除這次更新的影響,這樣一來(lái)直接我們就可以在樹(shù)上統(tǒng)計(jì)答案了。向下路徑的處理與向上路徑類(lèi)似。

code

#include<bits/stdc++.h>const int maxn=3e5+10;namespace IO {char buf[1<<15],*fs,*ft;inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }template<typename T>inline void read(T &x){x=0;T f=1, ch=getchar();while (!isdigit(ch) && ch^'-') ch=getchar();if (ch=='-') f=-1, ch=getchar();while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();x*=f;}char Out[1<<24],*fe=Out;inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }template<typename T>inline void write(T x,char str){if (!x) *fe++=48;if (x<0) *fe++='-', x=-x;T num=0, ch[20];while (x) ch[++num]=x%10+48, x/=10;while (num) *fe++=ch[num--];*fe++=str;} }using IO::read; using IO::write;int ver[maxn<<1],Next[maxn<<1],head[maxn],len; inline void add(int x,int y) {ver[++len]=y,Next[len]=head[x],head[x]=len; }namespace SGT {struct Orz{int l,r,z;}c[maxn*60];int num=0;inline void Change(int &x,int l,int r,int k,int z){if (!x) x=++num;c[x].z+=z;if (l==r) return ;int mid=(l+r)>>1;if (k<=mid) Change(c[x].l,l,mid,k,z);else Change(c[x].r,mid+1,r,k,z);}inline int query(int x,int l,int r,int k){if (l==r) return c[x].z;int mid=(l+r)>>1;if (k<=mid) return query(c[x].l,l,mid,k);else return query(c[x].r,mid+1,r,k);}inline int merge(int x,int y){if (!x) return y;if (!y) return x;c[x].l=merge(c[x].l,c[y].l);c[x].r=merge(c[x].r,c[y].r);c[x].z=c[x].z+c[y].z;return x;} }using SGT::Change; using SGT::query; using SGT::merge;namespace lca {int dfn[maxn],id;int f[maxn][21],dep[maxn];inline void dfs(int x){dfn[x]=++id;for (int i=1; i<=20; ++i) f[x][i]=f[f[x][i-1]][i-1];for (int i=head[x]; i; i=Next[i]){int y=ver[i];if (y==f[x][0]) continue;f[y][0]=x;dep[y]=dep[x]+1;dfs(y);}}inline int LCA(int x,int y){if (dep[x]>dep[y]) std::swap(x,y);for (int i=20; i>=0; --i)if (dep[y]-(1<<i)>=dep[x]) y=f[y][i];if (x==y) return x;for (int i=20; i>=0; --i)if (f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];return f[x][0];} }using lca::dfs; using lca::LCA; using lca::dep; using lca::f;int tot,n,m,u[maxn],v[maxn]; int ans[maxn],w[maxn]; inline void get(int x) {for (int i=head[x]; i; i=Next[i]){int y=ver[i];if (y==f[x][0]) continue;get(y);u[x]=merge(u[x],u[y]), v[x]=merge(v[x],v[y]);}ans[x]=query(u[x],1,tot,dep[x]+w[x])+query(v[x],1,tot,w[x]-dep[x]+n); }int main() {read(n);read(m); tot=n<<1;for (int i=1,x,y; i<n; ++i) read(x),read(y),add(x,y),add(y,x);for (int i=1; i<=n; ++i) read(w[i]);dfs(1);for (int i=1,x,y; i<=m; ++i){read(x),read(y);int a=LCA(x,y);Change(u[x],1,tot,dep[x],1);Change(u[a],1,tot,dep[x],-1);Change(v[y],1,tot,dep[x]-(dep[a]<<1)+n,1);Change(v[f[a][0]],1,tot,dep[x]-(dep[a]<<1)+n,-1);}get(1);for (int i=1; i<=n; ++i) write(ans[i],' '); *IO::fe--;//防 BZOJIO::flush();return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/G-hsm/p/11426646.html

總結(jié)

以上是生活随笔為你收集整理的BZOJ 4719: [Noip2016]天天爱跑步 线段树合并的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。