测试点1~2:暴力。

测试点3~4:可以将边按r从大到小排序不断加入,然后用并茶几维护深度。好像也可以用猫树做。

好吧其他的部分分并没有看懂。

正解:

线段树分治,求出每个速度的答案。

对于速度区间$[L,R]$,将完全包含这个区间的边加入,对于其余的边,按照和mid的关系分到左右儿子,这里的一条边有可能同时分到两个儿子所以直接塞vector就行了。

那么到达叶子区间时,满足条件的树的结构已经出来了,答案就是这些联通块的直径。

那么大体思路已经清晰了,如何动态维护树的结构呢?lct!!!并查集即可,维护联通块直径的两个端点,合并时分6中情况讨论即可,注意由于递归完左儿子后还要处理右儿子,所以左儿子中连的边都要清掉,于是并查集不能路径压缩,按秩合并即可(然而我故意把size大的合并到size小的还是A掉了)。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define re register
#define co const
#define rec re co
#define LL long long
using namespace std;
struct edge
{
int u,v,nxt,l,r;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define l(x) ed[x].l
#define r(x) ed[x].r
#define n(x) ed[x].nxt
friend bool operator < (edge a,edge b)
{return a.r>b.r;}
}ed[];
int first[],num_e=;
#define f(x) first[x]
int n,m;
int f[][],dep[],size[];
int ttop[],son[],dfn[],id[],cnt;
void dfs1(int x)
{
size[x]=;
for(int i=f(x);i;i=n(i))
if(v(i)!=f[x][])
{
f[v(i)][]=x;dep[v(i)]=dep[x]+;
dfs1(v(i));size[x]+=size[v(i)];
if(size[v(i)]>size[son[x]])son[x]=v(i);
}
}
void dfs2(int x,int t)
{
ttop[x]=t;dfn[x]=++cnt;id[cnt]=x;
if(son[x])dfs2(son[x],t);
for(int i=f(x);i;i=n(i))
if(v(i)!=f[x][]&&v(i)!=son[x])
dfs2(v(i),v(i));
}
inline int LCA(int x,int y)
{
while(ttop[x]!=ttop[y])
{
if(dep[ttop[x]]>dep[ttop[y]])swap(x,y);
y=f[ttop[y]][];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
#define st sta[top]
#define st2 sta2[top2]
#define st3 sta3[top3]
struct node{int id,pu,pv;}sta[];int top;
struct node2{int id,of;}sta2[];int top2;
struct node3{int id,ad;}sta3[];int top3;
vector<int> in[];
int fa[],u[],v[],al[],siz[];
int get(re int x){return fa[x]==x?x:get(fa[x]);}
LL lenth(re int u,re int v){return dep[u]+dep[v]-dep[LCA(u,v)]*;}
void solve(re int l,re int r,rec int x,re int res)
{
int mid=(l+r)>>,tem=top,tem2=top2,tres=res,tem3=top3;
for(int i=;i<in[x].size();i++)
if(l(in[x][i])<=l&&r(in[x][i])>=r)
{ int f1=get(u(in[x][i])),f2=get(v(in[x][i]));if(f1==f2)continue;
int gl;
if(siz[f1]>siz[f2])
{
fa[f1]=f2;gl=f2;siz[f2]+=siz[f1];
sta[++top]=(node){f2,u[f2],v[f2]};
sta2[++top2]=(node2){f1,f1};
sta3[++top3]=(node3){f2,siz[f1]};
}
else
{
fa[f2]=f1;gl=f1;siz[f1]+=siz[f2];
sta[++top]=(node){f1,u[f1],v[f1]};
sta2[++top2]=(node2){f2,f2};
sta3[++top3]=(node3){f1,siz[f2]};
}
int t1=u[f1],t2=u[f2],t3=v[f1],t4=v[f2];
int max1=lenth(t1,t2),
max2=lenth(t1,t3),
max3=lenth(t1,t4),
max4=lenth(t2,t3),
max5=lenth(t2,t4),
max6=lenth(t3,t4);
int maxn=max(max1,max2);maxn=max(maxn,max3);
maxn=max(maxn,max4);maxn=max(maxn,max5);maxn=max(maxn,max6);
if(maxn==max1)u[gl]=t1,v[gl]=t2;
else if(maxn==max2)u[gl]=t1,v[gl]=t3;
else if(maxn==max3)u[gl]=t1,v[gl]=t4;
else if(maxn==max4)u[gl]=t2,v[gl]=t3;
else if(maxn==max5)u[gl]=t2,v[gl]=t4;
else if(maxn==max6)u[gl]=t3,v[gl]=t4;
res=max(res,maxn);
}
else
{
if(l(in[x][i])<=mid)in[x*].push_back(in[x][i]);
if(r(in[x][i])> mid)in[x*+].push_back(in[x][i]);
}
if(l==r)
{
al[l]=res;
while(top>tem)u[st.id]=st.pu,v[st.id]=st.pv,top--;
while(top2>tem2)fa[st2.id]=st2.of,top2--;
while(top3>tem3)siz[st3.id]-=st3.ad,top3--;
res=tres;
return;
}
solve(l,mid,x*,res);solve(mid+,r,x*+,res);
while(top>tem)u[st.id]=st.pu,v[st.id]=st.pv,top--;
while(top2>tem2)fa[st2.id]=st2.of,top2--;
while(top3>tem3)siz[st3.id]-=st3.ad,top3--;
res=tres;
}
inline int read();
inline void add(rec int u,rec int v,rec int l,rec int r);
signed main()
{
// freopen("speed1.in","r",stdin);
// freopen("out.out","w",stdout); n=read(),m=read();
int tu,tv,tl,tr;
for(re int i=;i<n;i++)
{
tu=read(),tv=read(),tl=read(),tr=read();
add(tu,tv,tl,tr);add(tv,tu,tl,tr);
}
dfs1(),dfs2(,);
for(re int i=;i<=;i++)
for(re int j=;j<=n;j++)
f[j][i]=f[f[j][i-]][i-];
for(re int i=;i<=n;i++)fa[i]=u[i]=v[i]=i,siz[i]=;
for(re int i=;i<=num_e;i+=)in[].push_back(i);
solve(,n,,);
int q;
for(re int i=;i<=m;i++)
{
q=read();
printf("%d\n",al[q]);
}
}
inline int read()
{
int s=,f=;char a=getchar();
while(a<''||a>''){if(a=='-')f=-;a=getchar();}
while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
return s*f;
}
inline void add(rec int u,rec int v,rec int l,rec int r)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
l(num_e)=l;
r(num_e)=r;
n(num_e)=f(u);
f(u)=num_e;
}

HZOJ Dash Speed的更多相关文章

  1. Dash Speed【好题,分治,并查集按秩合并】

    Dash Speed Online Judge:NOIP2016十联测,Claris#2 T3 Label:好题,分治,并查集按秩合并,LCA 题目描述 比特山是比特镇的飙车圣地.在比特山上一共有 n ...

  2. csp-s模拟测试58「Divisors」·「Market」·「Dash Speed」

    A. Divisors   大概平均下来每个数也就几千约数吧....,直接筛 B. Market 可以把时间离线下来, 考试没有想到将询问离线,用数组存算了算只能过200的点,拿了70 事实上背包后直 ...

  3. LYDSY模拟赛day2 Dash Speed

    /* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; ,M=N*; ],nxt[N<< ...

  4. Claris’ Contest # 2 Day 2 Problem C. Dash Speed(分治+可持久化并查集+树剖)

    题面 题解 \(std\)爆栈了→_→ 我们先考虑一个简化的问题,如果只有加边的情况下如何动态维护直径 合并两棵树时,设\(a,b\)为\(A\)的直径的两个端点,\(c,d\)为\(B\)的直径的两 ...

  5. Dash Speed

    题目大意: 比特山是比特镇的飙车圣地.在比特山上一共有n 个广场,编号依次为1 到n,这些广场之间通过n - 1 条双向车道直接或间接地连接在一起,形成了一棵树的结构.因为每条车道的修建时间以及建筑材 ...

  6. [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

    题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...

  7. 联赛模拟测试8 Dash Speed 线段树分治

    题目描述 分析 对于测试点\(1\).\(2\),直接搜索即可 对于测试点\(3 \sim 6\),树退化成一条链,我们可以将其看成序列上的染色问题,用线段树维护颜色相同的最长序列 对于测试点\(7\ ...

  8. 【线段树分治】Dash Speed

    代码的美妙 #include <bits/stdc++.h> %:pragma GCC optimize(3) using namespace std; const int maxn=7e ...

  9. noip2016十连测round2

    A: Divisors 题意:给定 m 个不同的正整数 a 1 ,a 2 ,...,a m ,请对 0 到 m 每一个 k 计算,在区间 [1,n] 里有多少正整数 是 a 中恰好 k 个数的约数. ...

随机推荐

  1. 解决导入TensorFlow后出现警告的的问题解决:通过降低numpy的版本

    在原有基础上安装tensorflow 重新虚拟出一个环境安装tensorflow 安装 测试 大多教程都是重新虚拟出一个环境,原有环境就可以支持为什么还要重建一个新的环境,如果以后遇到坑了更新解释. ...

  2. LUOGU P2441 角色属性树

    题目描述 绪萌同人社是一个有趣的组织,该组织结构是一个树形结构.有一个社长,直接下属一些副社长.每个副社长又直接下属一些部长--. 每个成员都有一个萌点的属性,萌点属性是由一些质数的萌元素乘积构成(例 ...

  3. Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍

    无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和Ins ...

  4. jQuery 源码解析(二十九) 样式操作模块 尺寸详解

    样式操作模块可用于管理DOM元素的样式.坐标和尺寸,本节讲解一下尺寸这一块 jQuery通过样式操作模块里的尺寸相关的API可以很方便的获取一个元素的宽度.高度,而且可以很方便的区分padding.b ...

  5. 实践中了解到的CSS样式的优先级

    CSS三大特性——继承.优先级和层叠.这是在精通CSS中重点强调的内容. 继承即子类元素继承父类的样式,常用的可继承样式有:color,font,line-height,list-style,text ...

  6. 如何把pdf文档转化为word

    在工作中常常遇到大量的pdf文档,再加工进行处理文件,特别的不方便,需要转换为WORD. 尝试如下: 使用wps自带的工具转换,提示需要是会员才能进行.否则只能进行5页以下的转换. 再想是不是又有个这 ...

  7. python中数字转换成字符串

    数字转换成字符串: num=123 str='%d' %num str就变成了"123"

  8. FileIntputStream / FileOutputStream 类

    FileInputStream类(重点)     (1)基本概念 java.io.FileInputStream类用于读取诸如图像之类的原始字节流.   (2)常用的方法 FileInputStrea ...

  9. 【python小随笔】pycharm的永久破解

    PS:这里有人会遇到第一次输入补丁的破解命令后,重启后启动不了软件,这个时候需要卸载(unstall把配置都得删除了),然后重新下载软件,再用这个步骤就OK了~~版本一定要低于最新版本两个以上,最好用 ...

  10. spark-ML之朴素贝叶斯

    训练语料格式 自定义五个类别及其标签:0 运费.1 寄件.2 人工.3 改单.4 催单.5 其他业务类. 从原数据中挑选一部分作为训练语料和测试语料  建立模型测试并保存 import org.apa ...