考试题Speed

Problem:

比特山是比特镇的飙车圣地。在比特山上一共有 \(n\) 个广场,编号依次为 \(1\)\(n\),这些广场之间通过

\(n − 1\) 条双向车道直接或间接地连接在一起,形成了一棵树的结构。

因为每条车道的修建时间以及建筑材料都不尽相同,所以可以用两个数字$ l_i, r_i $量化地表示一条车道

的承受区间,只有当汽车以不小于 \(l_i\) 且不大于 \(r_i\) 的速度经过这条车道时,才不会对路面造成伤害。

Byteasar 最近新买了一辆跑车,他想在比特山飙一次车。Byteasar 计划选择两个不同的点 \(,S, T,\)

后在它们树上的最短路径上行驶,且不对上面任意一条车道造成伤害。

Byteasar 不喜欢改变速度,所以他会告诉你他的车速。为了挑选出最合适的车速,Byteasar 一共会

向你询问 \(m\) 次。请帮助他找到一条合法的道路,使得路径上经过的车道数尽可能多。

Input

第一行包含两个正整数\(, n, m,\)表示广场的总数和询问的总数。

接下来 n − 1 行,每行四个正整数 \(,u_i, v_i, l_i, r_i,\)表示一条连接 \(u_i\)\(v_i\) 的双向车道,且承受区间为\([l_i, r_i]\)

接下来 m 行,每行一个正整数 \(q_i\),分别表示每个询问的车速。

Output

输出 m 行,每行一个整数,其中第 \(i\) 行输出车速为 \(i\) 时的最长路径的长度,如果找不到合法的路

径则输出 0。

对于 100% 的数据,\(1 ≤ u_i, v_i, q_i ≤ n, 1 ≤ l_i ≤ r_i ≤ n\)

线段树分治&&动态树&&可撤销并查集

预处理出所有车速时的答案,

在车速区间[1,n]进行递归

进入区间[l,r]时,将全部覆盖此速度区间的边加入。

离开时还原。

递归到叶子节点时计算答案。

答案是此时森林的最长链。

我们用并查集维护树的直径的两个端点,当合并两颗树时,答案只可能在这四个端点中产生,共6种情况,取最大值。
Code

const int N=70010,M=N*20;
int n,m,i,g[N],v[N<<1],nxt[N<<1],ed,cur,ans[N];
int size[N],f[N],d[N],son[N],top[N];
int fa[N],dep[N],A[N],B[N];
int G[262150],V[M],W[M],NXT[M],ED;
struct E{int t,x,y;E(){}E(int _t,int _x,int _y){t=_t,x=_x,y=_y;}}q[N<<2];
void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x){
  size[x]=1;
  for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
    f[v[i]]=x,d[v[i]]=d[x]+1;
    dfs(v[i]),size[x]+=size[v[i]];
    if(size[v[i]]>size[son[x]])son[x]=v[i];
  }
}
void dfs2(int x,int y){
  top[x]=y;
  if(son[x])dfs2(son[x],y);
  for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
}
int lca(int x,int y){
  for(;top[x]!=top[y];x=f[top[x]])if(d[top[x]]<d[top[y]])swap(x,y);
  return d[x]<d[y]?x:y;
}
int dis(int x,int y){return d[x]+d[y]-2*d[lca(x,y)];}
int F(int x){return fa[x]==x?x:F(fa[x]);}
void merge(int x,int y,int&ret){
  x=F(x),y=F(y);
  int u,v,t=-1,tmp;
  tmp=dis(A[x],B[x]);
  if(tmp>t)t=tmp,u=A[x],v=B[x];
  tmp=dis(A[x],A[y]);
  if(tmp>t)t=tmp,u=A[x],v=A[y];
  tmp=dis(A[x],B[y]);
  if(tmp>t)t=tmp,u=A[x],v=B[y];
  tmp=dis(B[x],A[y]);
  if(tmp>t)t=tmp,u=B[x],v=A[y];
  tmp=dis(B[x],B[y]);
  if(tmp>t)t=tmp,u=B[x],v=B[y];
  tmp=dis(A[y],B[y]);
  if(tmp>t)t=tmp,u=A[y],v=B[y];
  if(ret<t)ret=t;
  if(dep[x]==dep[y]){
    dep[x]++; 
    q[++cur]=E(0,x,0);
  }
  if(dep[x]<dep[y])swap(x,y);
  q[++cur]=E(1,y,0);
  q[++cur]=E(2,x,A[x]);
  q[++cur]=E(3,x,B[x]);
  fa[y]=x,A[x]=u,B[x]=v;
}
void retrace(int t){
  while(cur>t){
    if(!q[cur].t)dep[q[cur].x]--;
    if(q[cur].t==1)fa[q[cur].x]=q[cur].x;
    if(q[cur].t==2)A[q[cur].x]=q[cur].y;
    if(q[cur].t==3)B[q[cur].x]=q[cur].y;
    cur--;
  }
}
void ins(int x,int a,int b,int c,int d,int p,int q){
  if(c<=a&&b<=d){
    V[++ED]=p;
    W[ED]=q;
    NXT[ED]=G[x];
    G[x]=ED;
    return;
  }
  int mid=(a+b)>>1;
  if(c<=mid)ins(x<<1,a,mid,c,d,p,q);
  if(d>mid)ins(x<<1|1,mid+1,b,c,d,p,q);
}
void solve(int x,int a,int b,int ret){
  int pos=cur;
  for(int i=G[x];i;i=NXT[i])merge(V[i],W[i],ret);
  if(a==b){
    ans[a]=ret;
    retrace(pos);
    return;
  }
  int mid=(a+b)>>1;
  solve(x<<1,a,mid,ret);
  solve(x<<1|1,mid+1,b,ret);
  retrace(pos);
}
int main(){
  scanf("%d%d",&n,&m);
  for(i=1;i<n;i++){
    int x,y,l,r;
    scanf("%d%d%d%d",&x,&y,&l,&r);
    add(x,y),add(y,x);
    ins(1,1,n,l,r,x,y);
  }
  dfs(1);dfs2(1,1);
  for(i=1;i<=n;i++)fa[i]=A[i]=B[i]=i;
  solve(1,1,n,0);
  while(m--)scanf("%d",&i),printf("%d\n",ans[i]);
  return 0;
}

转载于:https://www.cnblogs.com/LLCSBlog/p/11178186.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
speedspeed-profile是Android N编译模式中的两种选项。speed是一种编译模式,旨在最大化运行时性能,而speed-profile则是一种部分编译模式,根据profile记录的热点函数来编译,也是为了最大化运行时性能。在Android N中,通过设置LOCAL_DEX_PREOPT_FLAGS参数来选择编译模式。如果没有指定编译过滤器,则默认使用speed模式,如果有配置LOCAL_DEX_PREOPT_GENERATE_PROFILE参数为true,则使用speed-profile模式,否则使用quicken模式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ART编译模式学习](https://blog.csdn.net/m0_53696288/article/details/127584582)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Android热修复技术 --- 兼容性问题深入](https://blog.csdn.net/qq_33235287/article/details/124079469)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [adb安装模式修改为speed模式、](https://blog.csdn.net/fan380485838/article/details/81908591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值