HZOJ Dash Speed
测试点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的更多相关文章
- Dash Speed【好题,分治,并查集按秩合并】
Dash Speed Online Judge:NOIP2016十联测,Claris#2 T3 Label:好题,分治,并查集按秩合并,LCA 题目描述 比特山是比特镇的飙车圣地.在比特山上一共有 n ...
- csp-s模拟测试58「Divisors」·「Market」·「Dash Speed」
A. Divisors 大概平均下来每个数也就几千约数吧....,直接筛 B. Market 可以把时间离线下来, 考试没有想到将询问离线,用数组存算了算只能过200的点,拿了70 事实上背包后直 ...
- LYDSY模拟赛day2 Dash Speed
/* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; ,M=N*; ],nxt[N<< ...
- Claris’ Contest # 2 Day 2 Problem C. Dash Speed(分治+可持久化并查集+树剖)
题面 题解 \(std\)爆栈了→_→ 我们先考虑一个简化的问题,如果只有加边的情况下如何动态维护直径 合并两棵树时,设\(a,b\)为\(A\)的直径的两个端点,\(c,d\)为\(B\)的直径的两 ...
- Dash Speed
题目大意: 比特山是比特镇的飙车圣地.在比特山上一共有n 个广场,编号依次为1 到n,这些广场之间通过n - 1 条双向车道直接或间接地连接在一起,形成了一棵树的结构.因为每条车道的修建时间以及建筑材 ...
- [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)
题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...
- 联赛模拟测试8 Dash Speed 线段树分治
题目描述 分析 对于测试点\(1\).\(2\),直接搜索即可 对于测试点\(3 \sim 6\),树退化成一条链,我们可以将其看成序列上的染色问题,用线段树维护颜色相同的最长序列 对于测试点\(7\ ...
- 【线段树分治】Dash Speed
代码的美妙 #include <bits/stdc++.h> %:pragma GCC optimize(3) using namespace std; const int maxn=7e ...
- noip2016十连测round2
A: Divisors 题意:给定 m 个不同的正整数 a 1 ,a 2 ,...,a m ,请对 0 到 m 每一个 k 计算,在区间 [1,n] 里有多少正整数 是 a 中恰好 k 个数的约数. ...
随机推荐
- Windows 常用工具 & 开发工具 & Chrome插件 & Firefox 插件 & 办公软件
常用工具 1.FastStone 8.0 2.印象笔记 3.Chrome 4.Beyond Compare 5.Everything 6.有道词典 7.文本编辑软件 EditPlus UltraEdi ...
- Vuejs实战项目四:权限校验
路由跳转参考文档:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html 在/src下创建permission.js进行权限 ...
- 彭亮—Python学习
1.1 Python简单介绍 1.2 安装Python和配置环境 1.配置Python 1.1 下载Python(直接去官网下载就可以) 1.2 安装Python(点解默认安装即可 ...
- 洛谷P3296 刺客信条
题意: 给你一棵树,有两组01权值a[]和b[].n <= 700 你要构造一个自己到自己的映射,使得整棵树的形态不变,且映射后的a[]和映射之前的b[]中不同元素尽量少. 解: 发现这个整棵树 ...
- 【html、CSS、javascript-12】jquery-效果
一.jQuery 效果- 隐藏和显示 通过 jQuery,您可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: $("#hide").click(func ...
- 原生js增加,移除类名
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux中管理员用户与普通用户之间的切换
使用su进行用户切换 管理员用户切换至普通用户: su [用户名] 使用su命令从高级别用户切换至低级别用户无需输入密码 普通用户切换至管理员用户: 普通用户切换至管理员用户使用 su - 使用l ...
- jnhs-java实体类的有参构造器 无参构造器Could not instantiate bean class 实体类No default constructor found
new一个对象的时候要用到构造函数, 例如Hello hello = new Hello();这时调用的是Hello的无参数构造方法; Hello hello = new Hello("hi ...
- activity与fragment之间的传递数据
首先activity之间的数据传递就是 用intent和intent+bundle intent 传递 Intent i= new Intent(MainActivity.this,TheAty.cl ...
- LintCode刷题笔记-- InterLeaving
标签: 动态规划 解题思路 1. 这道题最重要的是,存在三个字符串,但是并不需要两个二维矩阵来进行解,因为可以使用i+j-1来代表s3的下标,这样就可以通过i和j来遍历s3了.因为对于任何一个合法的交 ...