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

题解
\(std\)爆栈了→_→
我们先考虑一个简化的问题,如果只有加边的情况下如何动态维护直径
合并两棵树时,设\(a,b\)为\(A\)的直径的两个端点,\(c,d\)为\(B\)的直径的两个端点,那么新的树的直径一定是\(ab,ac,ad,bc,bd,cd\)中的一个
证明:新树的直径一定是原树的直径或一条经过\((u,v)\)的链(其中\((u,v)\)为新加的边),这条经过\((u,v)\)的链肯定是\(A\)中离\(u\)最远的点到\(u+(u,v)+v\)到\(B\)中离\(v\)最远的点,感性理解一下易知,其中前者必为\(a\)或\(b\),后者必为\(c\)或\(d\)
于是,我们可以对于每一个连通块维护直径的两个端点,每次合并两个连通块时用六个值里的最大值更新答案,顺便用并查集维护即可
然而现在不仅需要加边还需要删边,我们对速度进行分治,设分治区间为\((l,r)\),每一次将所有承受区间完全包含\((l,r)\)的边加入,剩下的继续递归下去
因为我们在回溯的时候需要把递归里的连通块关系给删掉,所以这里需要可持久化并查集,或者简单的说就是并查集的时候只按秩合并,不路径压缩
//minamoto
#include<bits/stdc++.h>
#define R register
#define pi pair<int,int>
#define fi first
#define se second
#define ls (p<<1)
#define rs (p<<1|1)
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
#define gg(u) for(vector<eg>::iterator it=pos[u].begin();it!=pos[u].end();++it)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res=1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[21];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=1e5+5,M=N<<5;
struct Gr{
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int dep[N],top[N],fa[N],sz[N],son[N];
void dfs1(int u){
sz[u]=1,dep[u]=dep[fa[u]]+1;
go(u)if(v!=fa[u]){
fa[v]=u,dfs1(v),sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t;if(!son[u])return;
dfs2(son[u],t);
go(u)if(!top[v])dfs2(v,v);
}
int LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
inline int dis(R int u,R int v){return dep[u]+dep[v]-(dep[LCA(u,v)]<<1);}
}G;
struct node{
int x,y,v;pi p;
node(){}
node(R int X,R int Y,R int V,R pi P):x(X),y(Y),v(V),p(P){}
}st[N];
struct eg{
int u,v;
eg(){}
eg(R int u,R int v):u(u),v(v){}
};
pi li[N];vector<eg>pos[M];
int fa[N],ans[N],dep[N];
int n,m,top;
int find(int x){return fa[x]==x?x:find(fa[x]);}
void ins(int p,int l,int r,int ql,int qr,int u,int v){
if(ql<=l&&qr>=r)return pos[p].push_back(eg(u,v)),void();
int mid=(l+r)>>1;
if(ql<=mid)ins(ls,l,mid,ql,qr,u,v);
if(qr>mid)ins(rs,mid+1,r,ql,qr,u,v);
}
void merge(int u,int v,int &ans){
// printf("%d %d ",u,v);
u=find(u),v=find(v);
int a=li[u].fi,b=li[u].se,c=li[v].fi,d=li[v].se,res=-1;
// printf("%d %d %d %d\n",a,b,c,d);
pi p;
if(cmax(res,G.dis(a,b)))p=pi(a,b);
if(cmax(res,G.dis(a,c)))p=pi(a,c);
if(cmax(res,G.dis(a,d)))p=pi(a,d);
if(cmax(res,G.dis(b,c)))p=pi(b,c);
if(cmax(res,G.dis(b,d)))p=pi(b,d);
if(cmax(res,G.dis(c,d)))p=pi(c,d);
cmax(ans,res);
if(dep[u]<dep[v])swap(u,v);
st[++top]=node(u,v,0,li[u]);
if(dep[u]==dep[v])++dep[u],st[top].v=1;
fa[v]=u,li[u]=p;
// printf("%d\n",res);
}
void del(int cur){
while(top>cur){
dep[st[top].x]-=st[top].v,fa[st[top].y]=st[top].y;
li[st[top].x]=st[top].p,--top;
}
}
void solve(int p,int l,int r,int res){
int now=top;
gg(p)merge(it->u,it->v,res);
if(l==r)ans[l]=res;
else{
int mid=(l+r)>>1;
solve(ls,l,mid,res);
solve(rs,mid+1,r,res);
}
del(now);
}
int x;
int main(){
// freopen("testdata.in","r",stdin);
freopen("speed.in","r",stdin);
freopen("speed.out","w",stdout);
n=read(),m=read();
fp(i,1,n-1){
int u=read(),v=read(),l=read(),r=read();
G.add(u,v),G.add(v,u);
ins(1,1,n,l,r,u,v);
}
G.dfs1(1),G.dfs2(1,1);
fp(i,1,n)fa[i]=i,li[i]=pi(i,i);
solve(1,1,n,0);
while(m--)x=read(),print(ans[x]);
return Ot(),0;
}
Claris’ Contest # 2 Day 2 Problem C. Dash Speed(分治+可持久化并查集+树剖)的更多相关文章
- The Preliminary Contest for ICPC Asia Xuzhou 2019 B. so easy (unordered_map+并查集)
这题单用map过不了,太慢了,所以改用unordered_map,对于前面删除的点,把它的父亲改成,后面一位数的父亲,初始化的时候,map里是零,说明它的父亲就是它本身,最后输出答案的时候,输出每一位 ...
- HDU 6326.Problem H. Monster Hunter-贪心(优先队列)+流水线排序+路径压缩、节点合并(并查集) (2018 Multi-University Training Contest 3 1008)
6326.Problem H. Monster Hunter 题意就是打怪兽,给定一棵 n 个点的树,除 1 外每个点有一只怪兽,打败它需要先消耗 ai点 HP,再恢复 bi点 HP.求从 1 号点出 ...
- CodeForces - 688C:NP-Hard Problem (二分图&带权并查集)
Recently, Pari and Arya did some research about NP-Hard problems and they found the minimum vertex c ...
- D. The Door Problem 带权并查集
http://codeforces.com/contest/776/problem/D 注意到每扇门都有两个东西和它连接着,那么,如果第i扇门的状态是1,也就是已经打开了,那么连接它的两个按钮的状态应 ...
- Dash Speed【好题,分治,并查集按秩合并】
Dash Speed Online Judge:NOIP2016十联测,Claris#2 T3 Label:好题,分治,并查集按秩合并,LCA 题目描述 比特山是比特镇的飙车圣地.在比特山上一共有 n ...
- AtCoder Beginner Contest 049 & ARC065 連結 / Connectivity AtCoder - 2159 (并查集)
Problem Statement There are N cities. There are also K roads and L railways, extending between the c ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集
Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...
- 1326: The contest(并查集+分组背包)
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1326 殷犇有很多队员.他们都认为自己是最强的,于是,一场比赛开始了~ 于是安叔主办了一场比赛,比赛 ...
- Codeforces 954I Yet Another String Matching Problem(并查集 + FFT)
题目链接 Educational Codeforces Round 40 Problem I 题意 定义两个长度相等的字符串之间的距离为: 把两个字符串中所有同一种字符变成另外一种,使得两个 ...
随机推荐
- Shiro身份认证---转
目录 1. Shro的概念 2. Shiro的简单身份认证实现 3. Shiro与spring对身份认证的实现 前言: Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境 ...
- [深入学习C#]C#实现多线程的方法:线程(Thread类)和线程池(ThreadPool)
简介 使用线程的主要原因:应用程序中一些操作需要消耗一定的时间,比如对文件.数据库.网络的访问等等,而我们不希望用户一直等待到操作结束,而是在此同时可以进行一些其他的操作. 这就可以使用线程来实现. ...
- codeforces 637D D. Running with Obstacles(dp,水题,贪心)
题目链接: D. Running with Obstacles time limit per test 2 seconds memory limit per test 256 megabytes in ...
- Linux下视频流媒体直播服务器搭建详解
目标: 搭建网络直播流媒体服务器系统(Linux操作系统) 背景: 用于OTT-TV大并发的直播和点播的一套流媒体服务器系统.支持N x 24小时录制回看和直播的服务器端解决方案. 解决方案: l ...
- C++ STL, set用法。 待更新zzzzz
set集合容器:实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,以保证每个子树根节点键值大于左子树所有节点的键值,小于右子树所有节点的键值:另外,还 ...
- 《Javascript高级程序设计》阅读记录(一):第二、三章
<Javascript高级程序设计>阅读记录(一) 这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释 ...
- bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...
- [转] 更新Flash CS6发布设置的目标播放器版本
目前Aodbe发布的最新版的Flash CS6,都不支持将Flash Player 11作为目标播放器版本发布.这个问题很容易解决,但涉及到的东西却比较多,我在这里将一一讲解.首先来个Setp by ...
- 【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference
目录(?)[-] 例子1ListPreference小例子 定义一个preferences XML文件 继承PreferenceActivity 用户定制偏好的读取 第一次运行时设置缺省值 设置Cat ...
- Java 编程规范,常见规范,命名规范,复杂度
方法/步骤 1. *不允许把多个短语句写在一行中,即一行只写一条语句 1. 示例:如下例子不符合规范. LogFilename now = null; LogFilename t ...