CF932F Escape Through Leaf
题面传送门
一开始没看到只能跳到子树内想了好久
有一个显然的dp方程:设为跳到子树内点的最小答案,则有方程
树的问题先从序列上考虑。
序列上似乎是简单的,如果将每个转移看成一条的直线,扔进李超线段树里面修改查询即可。
然后上树后自然想到线段树合并。每次如果两边都有节点那么就将其中一个节点的线段暴力插入另一棵树中。
时间复杂度是的好像不大过得去。
啊真的是两只log吗。
复杂度扯不清楚的东西就上势能分析,考虑每条线段的势能,当这条线段在线段树上下一层后减一,容易发现到为止。
每次使一条线段势能减一是的,所以总复杂度为,然而常数很大跑得稀烂
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define RI re int
#define ll long long
#define db double
#define lb long db
#define N 100000
#define M N*N+5
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-9)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
using namespace std;vector<int> S[N+5];
int n,m,k,A[N+5],cnt,B[N+5],x,y,Ro[N+5];ll dp[N+5];const int INF=1e5;
struct Line{ll k,b;I ll calc(int x){return x*k+b;}};
namespace Tree{
Line F[N+5<<5];int R[N+5<<5],L[N+5<<5];I void Ins(Line x,int &now,int l=-INF,int r=INF){
if(!now) {now=++cnt;F[now]=x;return;}if(F[now].calc(l)>=x.calc(l)&&F[now].calc(r)>=x.calc(r)) {F[now]=x;return;}if(l==r) return;if(F[now].calc(l)<=x.calc(l)&&F[now].calc(r)<=x.calc(r))return;
int m=l+r>>1;F[now].calc(m)>=x.calc(m)?(F[now].calc(l)>=x.calc(l)?Ins(F[now],R[now],m+1,r):Ins(F[now],L[now],l,m),F[now]=x,0):(F[now].calc(l)>=x.calc(l)?Ins(x,L[now],l,m):Ins(x,R[now],m+1,r),0);
}
I int ME(int x,int y,int l=-INF,int r=INF){if(!x||!y) return x|y;Ins(F[y],x,l,r);if(l==r) return x;int m=l+r>>1;L[x]=ME(L[x],L[y],l,m);R[x]=ME(R[x],R[y],m+1,r);return x;}
I ll Qry(int x,int now,int l=-INF,int r=INF){if(!now) return 1e18;int m=l+r>>1;ll Fs=(x<=m?Qry(x,L[now],l,m):Qry(x,R[now],m+1,r));return min(Fs,F[now].calc(x));}
}
I void dfs(int x,int La){int Fl=0;for(RI i:S[x]) i^La&&(dfs(i,x),Ro[x]=Tree::ME(Ro[x],Ro[i]),Fl=1);dp[x]=Fl*Tree::Qry(A[x],Ro[x]);Tree::Ins((Line){B[x],dp[x]},Ro[x]);}
int main(){
freopen("1.in","r",stdin);
RI i;scanf("%d",&n);for(i=1;i<=n;i++) scanf("%d",&A[i]);for(i=1;i<=n;i++) scanf("%d",&B[i]);for(i=1;i<n;i++)scanf("%d%d",&x,&y),S[x].push_back(y),S[y].push_back(x);dfs(1,0);for(i=1;i<=n;i++) printf("%lld ",dp[i]);
}
分类:
CodeForces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2021-02-15 Ybtoj #893. 「高斯消元」带权的图
2021-02-15 luogu P3389 【模板】高斯消元法
2021-02-15 Ybtoj #593. 「费用流」木棍问题
2021-02-15 Ybtoj #631. 「左偏树」次短路径