题目大意:

比特山是比特镇的飙车圣地。在比特山上一共有n 个广场,编号依次为1 到n,这些广场之间通过n - 1 条双向车道直接或间接地连接在一起,形成了一棵树的结构。
因为每条车道的修建时间以及建筑材料都不尽相同,所以可以用两个数字li; ri 量化地表示一条车道的承受区间,只有当汽车以不小于li 且不大于ri 的速度经过这条车道时,才不会对路面造成伤害。
Byteasar 最近新买了一辆跑车,他想在比特山飙一次车。Byteasar 计划选择两个不同的点S; T,然后在它们树上的最短路径上行驶,且不对上面任意一条车道造成伤害。
Byteasar 不喜欢改变速度,所以他会告诉你他的车速。为了挑选出最合适的车速,Byteasar 一共会向你询问m 次。请帮助他找到一条合法的道路,使得路径上经过的车道数尽可能多。

数据范围n,m<=70000.

题解:

(蒟蒻眼中)比较神的树上分治。做法分治[ l , r ] :(丑图奉上)

其中每一个矩形代表分治区间,圆代表提取答案的地方。

每当访问到矩形/圆时,将对应区间加的边更新并查集,然后不断用新集的直径更新当前答案。

(ps.当两棵树合并时,新树的直径一定在旧树的端点中产生。这里需要6次特判。)

每当返回时,将原来的更新取消。可以先记录栈的tl,然后将栈还原。

细节比较多,详细见代码:


upd:由于之前代码太丑被和谐,附上新代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
int n,m,hed[N],cnt,dep[N],siz[N],fa[N],son[N],tp[N];
struct EG
{
int to,nxt;
}e[N<<];
void ae(int f,int t)
{
e[++cnt].to = t;
e[cnt].nxt = hed[f];
hed[f] = cnt;
}
void dfs1(int u,int f)
{
fa[u]=f,dep[u]=dep[f]+,siz[u]=;
for(int j=hed[u],to;j;j=e[j].nxt)
if((to=e[j].to)!=f)
{
dfs1(to,u),siz[u]+=siz[to];
if(siz[son[u]]<siz[to])son[u]=to;
}
}
void dfs2(int u,int Top)
{
tp[u] = Top;
if(!son[u])return ;
dfs2(son[u],Top);
for(int j=hed[u],to;j;j=e[j].nxt)if((to=e[j].to)!=fa[u]&&to!=son[u])
dfs2(to,to);
}
int get_lca(int x,int y)
{
while(tp[x]!=tp[y])
{
if(dep[tp[x]]<dep[tp[y]])swap(x,y);
x = fa[tp[x]];
}
return dep[x]<dep[y]?x:y;
}
int get_dis(int x,int y){return dep[x]+dep[y]-*dep[get_lca(x,y)];}
struct Tree
{
int a,b,w;
Tree(){}
Tree(int a,int b,int w):a(a),b(b),w(w){}
Tree operator + (const Tree&x)const
{
Tree ret = Tree(a,b,w);int tmp;
if(ret.w<x.w)ret=x;
tmp=get_dis(a,x.a);if(ret.w<tmp)ret=Tree(a,x.a,tmp);
tmp=get_dis(a,x.b);if(ret.w<tmp)ret=Tree(a,x.b,tmp);
tmp=get_dis(b,x.a);if(ret.w<tmp)ret=Tree(b,x.a,tmp);
tmp=get_dis(b,x.b);if(ret.w<tmp)ret=Tree(b,x.b,tmp);
return ret;
}
};
int ans[N];
struct segtree
{
struct point
{
Tree s;
int ff,siz;
}p[N];
struct node
{
int u;point p0;
node(){}
node(int u,point p0):u(u),p0(p0){}
}sta[N<<];
int hd[N<<],ct,tl;
struct edge
{
int u,v,nxt;
}E[N<<];
void ae(int f,int u,int v)
{
E[++ct].u = u;
E[ct].v = v;
E[ct].nxt = hd[f];
hd[f] = ct;
}
void insert(int l,int r,int u,int ql,int qr,int&lp,int&rp)
{
if(l==ql&&r==qr){ae(u,lp,rp);return ;}
int mid = (l+r)>>;
if(qr<=mid)insert(l,mid,u<<,ql,qr,lp,rp);
else if(ql>mid)insert(mid+,r,u<<|,ql,qr,lp,rp);
else insert(l,mid,u<<,ql,mid,lp,rp),insert(mid+,r,u<<|,mid+,qr,lp,rp);
}
int findff(int u){return u==p[u].ff?u:findff(p[u].ff);}
void merge(int u,int v,int&now)
{
u = findff(u),v = findff(v);
if(u==v)return ;
if(p[u].siz>p[v].siz)swap(u,v);
sta[++tl]=node(u,p[u]),sta[++tl]=node(v,p[v]);
p[v].s=p[v].s+p[u].s,p[u].ff=v;
if(p[u].siz==p[v].siz)p[v].siz++;
now = max(now,p[v].s.w);
}
void rep(int las)
{
while(tl!=las)p[sta[tl].u]=sta[tl].p0,tl--;
}
void sol(int l,int r,int u,int now)
{
int tim = tl;
for(int j=hd[u];j;j=E[j].nxt)
merge(E[j].u,E[j].v,now);
if(l==r){ans[l]=now;rep(tim);return ;}
int mid = (l+r)>>;
sol(l,mid,u<<,now);sol(mid+,r,u<<|,now);
rep(tim);
}
}tr;
int main()
{
// freopen("tt.in","r",stdin);
read(n),read(m);
for(int u,v,l,r,i=;i<n;i++)
{
read(u),read(v),read(l),read(r);
ae(u,v),ae(v,u);tr.insert(,n,,l,r,u,v);
}
dfs1(,),dfs2(,);
for(int i=;i<=n;i++)
tr.p[i].ff=i,tr.p[i].siz=,tr.p[i].s=Tree(i,i,);
tr.sol(,n,,);
for(int i=,x;i<=m;i++)
read(x),printf("%d\n",ans[x]);
return ;
}

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. [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

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

  6. HZOJ Dash Speed

    测试点1-2:暴力. 测试点3-4:可以将边按r从大到小排序不断加入,然后用并茶几维护深度.好像也可以用猫树做. 好吧其他的部分分并没有看懂. 正解: 线段树分治,求出每个速度的答案. 对于速度区间$ ...

  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. MVC5 + EF6 简单示例(转载)

    原文地址:http://www.cnblogs.com/panchunting/p/creating-an-entity-framework-data-model-for-an-asp-net-mvc ...

  2. tyvj 1666 城市建设【最小生成树】

    -Wall是个好东西,要不然我至死都看不出来我把(b[i]+b[j])写成了(b[i],b[j])-- 还是来自lyd的题解: (其实原来课件第一行式子写错了没有-1,然而我用sai手画了一个上去hh ...

  3. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

  4. jsp标准标签库——jstl

    JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. 除了这些,它还提供 ...

  5. PhpStorm Xdebug远程调试环境搭建原理分析及问题排查

    2017年05月26日  经验心得 目录   一. 环境介绍 二. 远程环境配置 2.2 Xdebug安装 2.3 配置 三. 本地phpstorm配置 3.1 下载远程代码 3.2 添加php解释器 ...

  6. 思维题 Gym 100553A Alter Board

    题目传送门 /* 题意:一个n×m的矩形,相邻的颜色不同,黑或白.问最少的翻转次数,每次翻转可指定任意一个子矩形 思维题:最少要把偶数行和列翻转,也就是n/2+m/2次 */ #include < ...

  7. 找规律/贪心 Codeforces Round #310 (Div. 2) A. Case of the Zeros and Ones

    题目传送门 /* 找规律/贪心:ans = n - 01匹配的总数,水 */ #include <cstdio> #include <iostream> #include &l ...

  8. sdut1283Five in a Row, Again

    一简单的状压题 比赛时跑偏了 ,脑子最近乱的跟浆糊似得呢.. #include <iostream> #include<cstdio> #include<cstring& ...

  9. visual studio 2015 key vs2015密钥

    Visual Studio Professional 2015简体中文版(专业版)KEY:HMGNV-WCYXV-X7G9W-YCX63-B98R2Visual Studio Enterprise 2 ...

  10. java之数据处理,小数点保留位数

    1.返回字符串类型,保留后两位: public static String getRate(Object d) { return String.format("%.2f", d); ...