YbtOJ#763-攻城略池【线段树合并】
生活随笔
收集整理的這篇文章主要介紹了
YbtOJ#763-攻城略池【线段树合并】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:http://www.ybtoj.com.cn/problem/763
題目大意
給出nnn個點的一棵樹,每個di=0d_i=0di?=0的點每秒會產生一個士兵往根節點走,走到一個節點讓一個節點did_idi?減一(為000就不管)。
求需要多久才能讓所有點的ddd值變為000
1≤n≤105,1≤di≤1081\leq n\leq10^5,1\leq d_i\leq 10^81≤n≤105,1≤di?≤108
解題思路
考慮求出每個點did_idi?值變成000的時間tit_iti?。
對于一個節點xxx,disxdis_xdisx?表示根節點到xxx的距離,那么它在時刻TTT時的減少數量是
∑y∈subtreexmax{T?ty?disy+disx,0}\sum_{y\in subtree_x}max\{T-t_y-dis_y+dis_x,0\}y∈subtreex?∑?max{T?ty??disy?+disx?,0}
我們可以每次把新得到的ty?disyt_y-dis_yty??disy?壓入線段樹,然后每次合并上去后再在線段樹上面二分出答案。
時間復雜度O(nlog?n)O(n\log n)O(nlogn)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10,inf=2e8; struct node{ll to,next,w; }a[N<<1]; ll n,tot,cnt,ans,ls[N],d[N],t[N],rt[N],dep[N]; void addl(ll x,ll y,ll w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;return; } struct SegTree{ll w[N<<6],c[N<<6],ls[N<<6],rs[N<<6];void Change(ll &x,ll L,ll R,ll pos){if(!x)x=++cnt;w[x]+=pos;c[x]++;if(L==R)return;ll mid=(L+R)>>1;if(pos<=mid)Change(ls[x],L,mid,pos);else Change(rs[x],mid+1,R,pos);return;}ll Ask(ll x,ll L,ll R,ll k,ll zc,ll zw){if(L==R)return L;ll mid=(L+R)>>1,tmp=mid*(c[ls[x]]+zc)-w[ls[x]]-zw;if(tmp>=k)return Ask(ls[x],L,mid,k,zc,zw);return Ask(rs[x],mid+1,R,k,zc+c[ls[x]],zw+w[ls[x]]);}ll Merge(ll x,ll y,ll l,ll r){if(!x||!y)return x+y;w[x]=w[x]+w[y];c[x]=c[x]+c[y];if(l==r)return x;ll mid=(l+r)>>1;ls[x]=Merge(ls[x],ls[y],l,mid);rs[x]=Merge(rs[x],rs[y],mid+1,r);return x;} }T; void dfs(ll x,ll fa){for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dep[y]=dep[x]+a[i].w;dfs(y,x);rt[x]=T.Merge(rt[x],rt[y],0,inf);}t[x]=max(0ll,T.Ask(rt[x],0,inf,d[x],0,0)-dep[x]);T.Change(rt[x],0,inf,t[x]+dep[x]);ans=max(ans,t[x]);return; } signed main() { // freopen("conquer.in","r",stdin); // freopen("conquer.out","w",stdout);scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&d[i]);for(ll i=1;i<n;i++){ll x,y,w;scanf("%lld%lld%lld",&x,&y,&w);addl(x,y,w);addl(y,x,w);}dfs(1,1);printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的YbtOJ#763-攻城略池【线段树合并】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小欢喜全体演员表 全体演员详细介绍
- 下一篇: P4542-[ZJOI2011]营救皮卡