CF739B Alyona and a tree 樹上差分
阿新 • • 發佈:2018-10-01
dfs vector con getch get pac += == tro
,\(v\)間的點都能控制\(u\)
故\(dfs\)往下掃,將\(dis(u,v)<=a[u]\)拆成\(dis[v]<=dis[u]-a[u]\)用\(vector\)存當前點的\(dis[x]\),若子樹中的點的\(dis[u]-a[u]\)找到從根開始第一個滿足該性質的點,則該點到\(u\)點路徑中所有的點都滿足要求
然後差分做,返回的時候清除節點,用子節點更新當點節點
題目描述
\(Alyona有一棵有 n個節點的樹。這棵樹的根節點是 1。在每個節點裏,Alyona寫了一個正整數,在節點 i 她寫了正整數a_i 。另外,她在這棵樹上的每條邊上寫了一個正整數(不同邊上可能有不同的數)。 讓我們定義 dist(v,u) 作為從 v 到 u 的簡單路徑上的邊權和。 當且僅當 u 在 v 的子樹中並且 dist(v,u)<=a_u,頂點 v 控制頂點 u(v!=u) 。Alyona想在某些頂點定居。為了做到這件事,她想知道在每個節點 v 能控制幾個節點。\)
對於\(u\),\(v\)兩點,若\(dis(u,v)<=a[u]\),則u,v間的點都滿足當前性質,即滿足\(u\)
故\(dfs\)往下掃,將\(dis(u,v)<=a[u]\)拆成\(dis[v]<=dis[u]-a[u]\)用\(vector\)存當前點的\(dis[x]\),若子樹中的點的\(dis[u]-a[u]\)找到從根開始第一個滿足該性質的點,則該點到\(u\)點路徑中所有的點都滿足要求
然後差分做,返回的時候清除節點,用子節點更新當點節點
#include <bits/stdc++.h> #define For(i,a,b) for(int i=(a);i<=(b);i++) #define Dec(i,a,b) for(int i=(a);i>=(b);i--) const int maxn=2e5+10; const int k=448; typedef long long ll; using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline ll readll(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int ans[maxn]; ll dis[maxn],a[maxn]; vector<ll>val[maxn]; vector<int>G[maxn]; vector<pair<ll,int> >que; //對於u,v兩點,若dis(u,v)<=a[u],則u,v間的點都滿足當前性質,即滿足u,v間的點都能控制u //故dfs往下掃,將dis(u,v)<=a[u]拆成dis[v]<=dis[u]-a[u]用vector存當前點的dis[x],若子樹中的點的dis[u]-a[u]找到從根開始第一個滿足該性質的點,則該點到u點路徑中所有的點都滿足要求 //然後差分做,返回的時候清除節點 void dfs(int x,int fa){ ans[x]=1; ll t=dis[x]-a[x]; int pos=lower_bound(que.begin(),que.end(),make_pair(t,0))-que.begin()-1; if(pos>=0)ans[que[pos].second]--; que.push_back(make_pair(dis[x],x)); For(i,0,(int)G[x].size()-1){ int u=G[x][i]; if(u==fa)continue; dis[u]=dis[x]+val[x][i]; dfs(u,x); ans[x]+=ans[u]; } que.pop_back(); } int main(){ int n; n=read(); For(i,1,n)a[i]=readll(); int v; ll cost; For(i,2,n){ v=read();cost=readll(); val[i].push_back(cost); val[v].push_back(cost); G[i].push_back(v); G[v].push_back(i); } dfs(1,-1); For(i,1,n)printf("%d ",ans[i]-1); return 0; }
CF739B Alyona and a tree 樹上差分