luogu2542 航线规划 (树链剖分)
不会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 航线规划 (树链剖分)的更多相关文章
- BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )
首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键 ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- BZOJ 1969: [Ahoi2005]LANE 航线规划 [树链剖分 时间倒流]
题意: 一张图,删除边,求两点之间的割边数量.保证任意时刻图连通 任求一棵生成树,只有树边可能是割边 时间倒流,加入一条边,就是两点路径上的边都不可能是割边,区间覆盖... 然后本题需要把边哈希一下, ...
- bzoj1969 [Ahoi2005]LANE 航线规划 树链剖分
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1969 题解 如果我们把整个图边双联通地缩点,那么最终会形成一棵树的样子. 那么在这棵树上,\( ...
- 洛谷 P2542 [AHOI2005]航线规划 树链剖分_线段树_时光倒流_离线
Code: #include <map> #include <cstdio> #include <algorithm> #include <cstring&g ...
- 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分
题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...
- 【BZOJ2402】陶陶的难题II 分数规划+树链剖分+线段树+凸包
题解: 首先分数规划是很明显的 然后在于我们如何要快速要求yi-mid*xi的最值 这个是看了题解之后才知道的 这个是斜率的一个基本方法 我们设y=mid*x+z 那么显然我们可以把(x,y)插入到一 ...
- bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)
只有删边,想到时间倒流. 倒着加边,因为保证图连通,所以一开始一定至少是一棵树.我们先建一棵树出来,对于每一条非树边,两个端点在树上这段路径的边就不会变成关键边了,所以将它们对答案的贡献删去,那么直接 ...
- [BZOJ2402]陶陶的难题II(树链剖分+线段树维护凸包+分数规划)
陶陶的难题II 时间限制:40s 空间限制:128MB 题目描述 输入格式 第一行包含一个正整数N,表示树中结点的个数. 第二行包含N个正实数,第i个数表示xi (1<=xi<= ...
随机推荐
- [Oracle][Standby][PDB]在PDB中修改参数,设置范围为 SPFILE,报 ORA-65099错误
[Oracle][Standby][PDB]在PDB中修改参数,设置范围为 SPFILE,报 ORA-65099错误 在Data Gaurd 的 Standby (或 CDB 是 Read Only ...
- python第二周。2019.4.13
1, 我绘制大蟒蛇就是..保存也对着呢,你要是打开文件的话,先闪个黑屏,再闪个白屏..自动退出,然后啥都没了. 我觉得是我代码编错了...再来一遍! 这次到可以,但是这个大蟒蛇好像没有回头... 刚才 ...
- C# 爬虫 正则、NSoup、HtmlAgilityPack、Jumony四种方式抓取小说
心血来潮,想爬点小说.通过百度选择了个小说网站,随便找了一本小说http://www.23us.so/files/article/html/13/13655/index.html. 1.分析html规 ...
- React.js 入门与实战课程思维导图
原文发表于我的技术博客 我在慕课网的「React.js 入门与实战之开发适配PC端及移动端新闻头条平台」课程已经上线了,在这里分享了课程中的思维导图,供大家参考. 原文发表于我的技术博客 此导图为课程 ...
- openssl版本升级操作记录
需要部署nginx的https环境,之前是yum安装的openssl,版本比较低,如下: [root@nginx ~]# yum install -y pcre pcre-devel openssl ...
- C++ string简单的使用技巧
截取substr //string的操作 #include<iostream> using namespace std; int main() { string a,b; a=" ...
- 《Linux内核分析》实践2
<Linux及安全>实践2 一.Linux基本内核模块 1.1什么是内核模块 linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一 ...
- 广商博客冲刺第六七天new
第四五天沖刺傳送門 第一版的網頁已經放到 云服務器(估計快到期了) 傳送門. (不怎么會玩服務器啊..求指教..目前問題如下: 1.我的電腦mysql密碼跟服務器的密碼不一樣..上傳的時候要把代碼里面 ...
- SVN入门教程
1. 什么是SVN SVN全名Subversion,即版本控制系统.SVN与CVS一样,是一个跨平台的软件,支持大多数常见的操作系统. 作为一个开源的版本控制系统,Subversion管理者随时间改变 ...
- Delphi的idhttp报IOHandler value is not valid错误的原因[转]
出现这种问题的原因是由于访问的 URL地址为https或存在其跳转地址为https. 首先单纯使用idhttp是只能访问http,而https则需要搭配IdSSLIOHandlerSocketOpen ...