不会lct,所以只能树剖乱搞

一般这种删边的题都是离线倒着做,变成加边

他要求的结果其实就是缩点以后两点间的距离。

然后先根据最后剩下的边随便做出一个生成树,然后假装把剩下的边当成加边操作以后处理

这样的话,就可以做树剖来维护现在的两点间距离。

然后考虑加边,其实就是加了一条边然后某一处成环了,缩成了一个点。

这样的话,就可以把这条边两个端点间的距离都改成0,假装缩了点。

最后再倒着输出答案就行了。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#define inf 0x3f3f3f3f
#define LL long long int
using namespace std;
const int maxn=,maxm=,maxq=; inline LL rd(){
LL x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Edge{
int a,b,ne;bool used,flag;
}eg[maxm*];
int N,M;
int egh[maxn],ect;
int que[maxq][],ans[maxq],qct;
int fa[maxn],dep[maxn],wson[maxn],siz[maxn],top[maxn],root[maxn],len[maxn];
int ch[maxn*][],val[maxn*],pct;
bool laz[maxn*];
map<int,int> mp; inline void adeg(int a,int b){
eg[ect].a=a;eg[ect].b=b;eg[ect].ne=egh[a];eg[ect].used=;egh[a]=ect++;
} inline void pushdown(int p){
if(!laz[p]) return;
val[ch[p][]]=val[ch[p][]]=laz[p]=;
laz[ch[p][]]=laz[ch[p][]]=;
}
inline void update(int p){pushdown(p);val[p]=val[ch[p][]]+val[ch[p][]];} void build(int &p,int l,int r){
p=++pct;
if(l==r) val[p]=;
else{
int m=l+r>>;
build(ch[p][],l,m);build(ch[p][],m+,r);
update(p);
}
} int query(int p,int l,int r,int x,int y){
if(x<=l&&r<=y) return val[p];
else{
pushdown(p);int m=l+r>>,re=;
if(x<=m) re+=query(ch[p][],l,m,x,y);
if(y>=m+) re+=query(ch[p][],m+,r,x,y);
return re;
}
} void change(int p,int l,int r,int x,int y){
if(x<=l&&r<=y){
val[p]=;laz[p]=;pushdown(p);
}else if(val[p]!=){
pushdown(p);int m=l+r>>;
if(x<=m) change(ch[p][],l,m,x,y);
if(y>=m+) change(ch[p][],m+,r,x,y);
update(p);
}
} void dfs1(int x){
siz[x]=;int ma=;
for(int i=egh[x];i!=-;i=eg[i].ne){
int b=eg[i].b;
if(!eg[i].used||dep[b]) continue;
eg[i].flag=eg[i^].flag=;
fa[b]=x;dep[b]=dep[x]+;
dfs1(b);siz[x]+=siz[b];
if(siz[b]>ma) ma=siz[b],wson[x]=b;
}
} void dfs2(int x){
if(x!=wson[fa[x]]){int d=;
for(int i=x;i;i=wson[i]) top[i]=x,d++;
build(root[x],,d);len[x]=d;
}for(int i=egh[x];i!=-;i=eg[i].ne){
int b=eg[i].b;
if(eg[i].flag&&fa[x]!=b) dfs2(b);
}
} void solveC(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(root[top[x]],,len[top[x]],,dep[x]-dep[top[x]]+);x=fa[top[x]];
}if(x==y) return;
if(dep[x]>dep[y]) swap(x,y);
change(root[top[x]],,len[top[x]],dep[x]-dep[top[x]]+,dep[y]-dep[top[y]]+);
}
int solveQ(int x,int y){
int re=;
while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y);
re+=query(root[top[x]],,len[top[x]],,dep[x]-dep[top[x]]+);x=fa[top[x]];
}if(x==y) return re;
if(dep[x]>dep[y]) swap(x,y);
return re+query(root[top[x]],,len[top[x]],dep[x]-dep[top[x]]+,dep[y]-dep[top[y]]+);
} int main(){
int i,j,k;
N=rd();M=rd();memset(egh,-,sizeof(egh));
for(i=;i<=M;i++){
int a=rd(),b=rd();
mp[a*N+b]=ect;adeg(a,b);
mp[b*N+a]=ect;adeg(b,a);
}while(++qct){
int a=rd();if(a==-) break;
int b=rd(),c=rd();
que[qct][]=a;que[qct][]=b;que[qct][]=c;
if(!a){
int x=mp[b*N+c];
eg[x].used=eg[x^].used=;
}
}dep[]=;dfs1();dfs2();
for(i=;i<ect;i++){
if((!eg[i].flag)&&eg[i].used) solveC(eg[i].a,eg[i].b);
}int act=;
for(i=qct-;i;i--){
if(!que[i][]) solveC(que[i][],que[i][]);
else ans[++act]=solveQ(que[i][],que[i][]);
}for(i=act;i;i--) printf("%d\n",ans[i]);
return ;
}

luogu2542 航线规划 (树链剖分)的更多相关文章

  1. BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )

    首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键 ...

  2. 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树

    题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...

  3. BZOJ 1969: [Ahoi2005]LANE 航线规划 [树链剖分 时间倒流]

    题意: 一张图,删除边,求两点之间的割边数量.保证任意时刻图连通 任求一棵生成树,只有树边可能是割边 时间倒流,加入一条边,就是两点路径上的边都不可能是割边,区间覆盖... 然后本题需要把边哈希一下, ...

  4. bzoj1969 [Ahoi2005]LANE 航线规划 树链剖分

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1969 题解 如果我们把整个图边双联通地缩点,那么最终会形成一棵树的样子. 那么在这棵树上,\( ...

  5. 洛谷 P2542 [AHOI2005]航线规划 树链剖分_线段树_时光倒流_离线

    Code: #include <map> #include <cstdio> #include <algorithm> #include <cstring&g ...

  6. 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分

    题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...

  7. 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包

    题解: 首先分数规划是很明显的 然后在于我们如何要快速要求yi-mid*xi的最值 这个是看了题解之后才知道的 这个是斜率的一个基本方法 我们设y=mid*x+z 那么显然我们可以把(x,y)插入到一 ...

  8. bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)

    只有删边,想到时间倒流. 倒着加边,因为保证图连通,所以一开始一定至少是一棵树.我们先建一棵树出来,对于每一条非树边,两个端点在树上这段路径的边就不会变成关键边了,所以将它们对答案的贡献删去,那么直接 ...

  9. [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)

    陶陶的难题II 时间限制:40s      空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...

随机推荐

  1. hadoop_spark伪分布式实验环境搭建和运行实例详细教程

    hadoop+spark伪分布式环境搭建 安装须知 单机模式(standalone): 该模式是Hadoop的默认模式.这种模式在一台单机上运行,没有分布式文件系统,而是直接读写本地操作系统的文件系统 ...

  2. 【下一代核心技术DevOps】:(三)私有代码库阿里云Git使用

    1. 引言 使用DevOps肯定离不开和代码的集成.所以要想跑通整套流程,代码库的选型也是非常重要的.否则无法实现持续集成.目前比较常用的代码管理有SVN和GIt 如果还使用SVN的,建议尽早迁移到G ...

  3. Week2 代码复查

    代码复查 http://blog.fogcreek.com/increase-defect-detection-with-our-code-review-checklist-example/ 这篇博客 ...

  4. Practice3 阅读《构建之法》1-5章

    第一章:概论 本章主要是讲了软件工程的基本概念,软件工程的最终目标是创造“足够好”的软件. 提出问题:什么是BUG?(出自1.2.5节) 答:就我个人而言,在许多游戏中也有许多的BUG,BUG这一词在 ...

  5. jquery打印页面(jquery.jqprint)

    使用jquery进行打印时,所需js包:jquery-1.4.4.min.js.jquery.jqprint-0.3.js 但如果使用高版本的jquery(jquery-1.9.1.min.js)时, ...

  6. 06-java学习-方法的学习

    方法定义 方法类型 方法涉及的知识: 修饰符.返回类型,命名规则,参数列表 方法常见错误 方法概念的深入理解 为什么会有方法? 方法帮助解决哪些问题? 方法可以简化复杂问题的解决

  7. 10-Python3从入门到实战—基础之函数

    Python从入门到实战系列--目录 函数的定义 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数的语法 def 函数名(参数列表): 函数体 函数代码块以 def 关键词开头 ...

  8. spring 整合

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. Max length of title attribute in html

    测了一下chrome是1024个utf-8字符. 具体可见: http://stackoverflow.com/questions/8516235/max-length-of-title-attrib ...

  10. JavaScript 模拟 HashMap例子

    function map(){    var map = {}; // Map map = new HashMap();        var key = "key";    va ...