YbtOJ#763-攻城略池【线段树合并】

1|0正题

题目链接:http://www.ybtoj.com.cn/problem/763


1|1题目大意

给出n个点的一棵树,每个di=0的点每秒会产生一个士兵往根节点走,走到一个节点让一个节点di减一(为0就不管)。

求需要多久才能让所有点的d值变为0

1n105,1di108


1|2解题思路

考虑求出每个点di值变成0的时间ti

对于一个节点xdisx表示根节点到x的距离,那么它在时刻T时的减少数量是

ysubtreexmax{Ttydisy+disx,0}

我们可以每次把新得到的tydisy压入线段树,然后每次合并上去后再在线段树上面二分出答案。

时间复杂度O(nlogn)


1|3code

#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; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14425808.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(61)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示