【BZOJ1969】[Ahoi2005]LANE 航线规划 离线+树链剖分+线段树
【BZOJ1969】[Ahoi2005]LANE 航线规划
Description

Input
Output
Sample Input
1 2
1 3
3 4
4 5
4 2
1 1 5
0 4 2
1 5 1
-1
Sample Output
3
题解:既然能离线搞肯定要离线啦~由于保证了最后时刻图是联通的,所以我们先求出一棵生成树,然后反着往树上加边。每加一条边,就相当于将这条边覆盖的所有树边都打上标记,意味着它们不再是关键路径。查询时,看一下路径上有多少条未标记的边就行了。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <map>
#include <utility>
#define MP(A,B) make_pair(A,B)
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int maxm=200010;
const int maxn=30010;
typedef pair<int,int> pii;
int n,m,q,cnt;
int to[maxm],next[maxm],head[maxn],val[maxm],dep[maxn],fa[maxn],top[maxn],son[maxn],siz[maxn],p[maxn];
int s[maxn<<2],tag[maxn<<2],qa[maxm],qb[maxm],op[maxm],ans[maxm],pa[maxm],pb[maxm];
map<pii,int> mp;
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void build(int l,int r,int x)
{
if(l==r)
{
s[x]=(l!=1);
return ;
}
int mid=l+r>>1;
build(l,mid,lson),build(mid+1,r,rson);
s[x]=s[lson]+s[rson];
}
void pushdown(int x)
{
if(tag[x]) tag[lson]=tag[rson]=1,s[lson]=s[rson]=0,tag[x]=0;
}
void updata(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b)
{
s[x]=0,tag[x]=1;
return ;
}
pushdown(x);
int mid=l+r>>1;
if(a<=mid) updata(l,mid,lson,a,b);
if(b>mid) updata(mid+1,r,rson,a,b);
s[x]=s[lson]+s[rson];
}
int query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return s[x];
pushdown(x);
int mid=l+r>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return query(l,mid,lson,a,b)+query(mid+1,r,rson,a,b);
}
void add(int a,int b)
{
mp[MP(max(a,b),min(a,b))]=cnt,to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,next[cnt]=head[b],head[b]=cnt++;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i])
{
if(!dep[to[i]]&&!val[i])
{
dep[to[i]]=dep[x]+1,fa[to[i]]=x,dfs1(to[i]),siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
else
{
if(to[i]!=fa[x]&&!val[i]&&!val[i^1]) pa[++pa[0]]=x,pb[pa[0]]=to[i];
val[i]=1;
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp,p[x]=++p[0];
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=next[i])
if(!val[i]&&to[i]!=son[x])
dfs2(to[i],to[i]);
}
void modify(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
updata(1,n,1,p[top[x]],p[x]),x=fa[top[x]];
}
if(x==y) return ;
if(dep[x]>dep[y]) swap(x,y);
updata(1,n,1,p[x]+1,p[y]);
}
int ask(int x,int y)
{
int ret=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=query(1,n,1,p[top[x]],p[x]),x=fa[top[x]];
}
if(x==y) return ret;
if(dep[x]>dep[y]) swap(x,y);
return ret+query(1,n,1,p[x]+1,p[y]);
}
int main()
{
n=rd(),m=rd();
int i,a,b;
memset(head,-1,sizeof(head));
for(i=1;i<=m;i++) a=rd(),b=rd(),add(a,b);
while(1)
{
op[++q]=rd();
if(op[q]==-1) break;
qa[q]=rd(),qb[q]=rd();
if(!op[q])
{
a=mp[MP(max(qa[q],qb[q]),min(qa[q],qb[q]))];
val[a]=val[a^1]=1;
}
}
dep[1]=1,dfs1(1),dfs2(1,1),build(1,n,1);
for(i=1;i<=pa[0];i++) modify(pa[i],pb[i]);
for(i=q-1;i>=1;i--)
{
if(!op[i]) modify(qa[i],qb[i]);
else ans[i]=ask(qa[i],qb[i]);
}
for(i=1;i<q;i++) if(op[i]) printf("%d\n",ans[i]);
return 0;
}
//5 5 1 2 1 3 3 4 4 5 4 2 1 1 5 0 4 2 1 5 1 -1
【BZOJ1969】[Ahoi2005]LANE 航线规划 离线+树链剖分+线段树的更多相关文章
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分
题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- 2019西北工业大学程序设计创新实践基地春季选拔赛 I Chino with Rewrite (并查集+树链剖分+线段树)
链接:https://ac.nowcoder.com/acm/contest/553/I 思路:离线整棵树,用并查集维护下联通的情况,因为值只有60个,用2的x(1<=x<=60)次方表示 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 【bzoj3626】[LNOI2014]LCA 树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
随机推荐
- LeetCode OJ-- Search a 2D Matrix
https://oj.leetcode.com/problems/search-a-2d-matrix/ 具有数据递增性质的一个二维数组,对它进行二分搜索. 首先搜索target所在的行,再找列. c ...
- noip2013/day1/1/转圈游戏
总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 128000kB 描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从 ...
- workflow engine Ruote 安装
今天在安装gem安装Ruote的过程中遇到问题,改用bundle安装: steven@steven-Latitude-D630:/usr$ sudo mkdir bundel [sudo] passw ...
- Docking For WPF–AvalonDock
桌面程序的应用,不可避免的就会用到大量的布局控件,之前的一个项目也想过去做类似于Visual Studio的那种灵活的布局控件,也就是界面上的控件能够实现拖拽放置.隐藏.窗口化等一系列的操作,但由于开 ...
- delphi如何把一个整数转化为4个十六进制字节
var s:string; len:Integer; AData:TBytes; begin s:=IntToHex(149259,6);//返回6位字符串 len ...
- 【freeCodeCamp】免费晋级前台工程师呦!!!!
首页地址:https://www.freecodecamp.org/ GitHub:https://github.com/freeCodeCamp/freeCodeCamp ============= ...
- http://blog.csdn.net/LANGXINLEN/article/details/50421988
GitHub上史上最全的Android开源项目分类汇总 今天在看博客的时候,无意中发现了 @Trinea在GitHub上的一个项目 Android开源项目分类汇总, 由于类容太多了,我没有一个个完整地 ...
- Vbs脚本经典教材
转载:http://www.cnblogs.com/BeyondTechnology/archive/2011/01/10/1932440.html Vbs脚本经典教材(最全的资料还是MSDN) —为 ...
- PropertyGrid—隐藏某些Public属性
1.定义一个继承ControlDesigner 的类 public class MyControlDesigner:System.Windows.Forms.Design.ControlDesigne ...
- CF - 420B - Online Meeting(思维)
题意:n 个人參加线上会议.某经理记录了中间一段时间的 m 条上下线记录(1 ≤ n, m ≤ 105).+ 表示上线,- 表示下线. leader是指仅仅要有人在线,他都在线的人.求全部可能的lea ...