【BZOJ】1969: [Ahoi2005]LANE 航线规划
题目链接:
题解:
老夫实在是码不动了……
正着搞显然不好做,尝试倒着乱搞。先给被删除的边标记一个时间戳,先删除的时间戳大,同时维护询问时间戳,询问早的时间戳大。没被删除过的边时间戳都是0。然后瞎tarjan一次,建立双联通分量树。然后考虑每条被删除的边补会图中,相当于把两点所属双联通分量之间路径边权变为0。然后强行树剖一波即可。
(调死人啦!
代码:
#define Troy 10/19/2017
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
}
const int N=1e5+;
int n,m,q,ans[N];
struct Q{
int u,v,times,val;
inline void in(){
u=read(),v=read(),val=;
if(u>v) swap(u,v);
}
}query[N<<];
inline bool cmpx(Q a,Q b){
return a.u!=b.u?a.u<b.u:a.v<b.v;
}
inline bool cmpy(Q a,Q b){
return a.times<b.times;
}
struct edges{
int v;edges *last;
}edge[N<<],*head[N];int cnt;
inline void push(int u,int v){
edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
}
/**********************************************************************/
int dfn[N],low[N],bccno[N],idx,stk[N],top,bcc_cnt;
inline void tarjan(int x,int fa){
dfn[x]=low[x]=++idx;
stk[++top]=x;
for(edges *i=head[x];i;i=i->last) if(i->v!=fa){
if(!dfn[i->v]){
tarjan(i->v,x);
low[x]=min(low[x],low[i->v]);
}else
low[x]=min(low[x],dfn[i->v]);
}
if(dfn[fa]<low[x]){
bcc_cnt++;int t;
do{
t=stk[top--];
bccno[t]=bcc_cnt;
}while(t!=x);
}
}
/*****************************************************************/
int size[N],heavy[N],deep[N],g[N],f[N],tid[N];
inline void dfs(int x,int fa){
size[x]=;
for(edges *i=head[x];i;i=i->last)if(i->v!=fa){
deep[i->v]=deep[x]+;
f[i->v]=x;
dfs(i->v,x);
size[x]+=size[i->v];
if(size[i->v]>size[heavy[x]])
heavy[x]=i->v;
}
}
inline void dfs(int x,int fa,int grand){
tid[x]=++idx;
g[x]=grand;
if(heavy[x])
dfs(heavy[x],x,grand);
for(edges *i=head[x];i;i=i->last)
if(i->v!=fa&&i->v!=heavy[x])
dfs(i->v,x,i->v);
}
inline void init(){
n=read(),m=read();
for(int i=;i<=m;i++)
query[i].in();
sort(query+,query++m,cmpx);
int t=1e6;
while(){
int c=read(),a,b;
if(c==-) break;
a=read(),b=read();
if(a>b) swap(a,b);
if(c==){
int x=upper_bound(query+,query++m,(Q){a,b,,},cmpx)-query-;
query[x].times=t;
}else{
q++;
query[q+m]=(Q){a,b,t,};
}
t--;
}
sort(query+,query++q+m,cmpy);
for(int i=;i<=m+q&&query[i].times==;i++)
push(query[i].u,query[i].v),
push(query[i].v,query[i].u);
tarjan(,);
memset(head,,sizeof(head));cnt=;
for(int i=;i<=m+q&&query[i].times==;i++)
if(bccno[query[i].u]!=bccno[query[i].v])
push(bccno[query[i].u],bccno[query[i].v]),
push(bccno[query[i].v],bccno[query[i].u]);
dfs(,);
idx=;
dfs(,,);
}
/********************************************************************/
struct Tree{
Tree *son[];
int val;
}*root,tree[N<<];int t_cnt;
inline void build(Tree *&u,int l,int r){
u=tree+t_cnt;t_cnt++;
u->val=;
if(l==r){
u->son[]=u->son[]=NULL;
u->val=(l!=);
return;
}
int mid=l+r>>;
build(u->son[],l,mid);
build(u->son[],mid+,r);
for(int i=;i<;i++)
u->val+=u->son[i]->val;
}
inline void change(Tree *u,int l,int r,int x,int y){
if((x<=l&&r<=y)||u->val==){
u->val=;
return;
}
int mid=l+r>>;
if(y>mid)
change(u->son[],mid+,r,x,y);
if(x<=mid)
change(u->son[],l,mid,x,y);
u->val=;
for(int i=;i<;i++)
u->val+=u->son[i]->val;
}
inline int sum(Tree *u,int l,int r,int x,int y){
if(u->val==) return ;
if(x<=l&&r<=y)
return u->val;
int mid=l+r>>;
if(x>mid)
return sum(u->son[],mid+,r,x,y);
else if(y<=mid)
return sum(u->son[],l,mid,x,y);
else return sum(u->son[],l,mid,x,y)+sum(u->son[],mid+,r,x,y);
}
inline void change(int x,int y){
while(g[x]!=g[y]){
if(deep[g[x]]<deep[g[y]])
swap(x,y);
change(root,,idx,tid[g[x]],tid[x]);
x=f[g[x]];
}
if(x==y) return;
if(deep[x]>deep[y])
swap(x,y);
change(root,,idx,tid[x]+,tid[y]);
}
inline int sum(int x,int y){
int ret=;
while(g[x]!=g[y]){
if(deep[g[x]]<deep[g[y]])
swap(x,y);
ret+=sum(root,,idx,tid[g[x]],tid[x]);
x=f[g[x]];
}
if(x!=y){
if(deep[x]>deep[y])
swap(x,y);
ret+=sum(root,,idx,tid[x]+,tid[y]);
}
return ret;
}
inline void work(){
build(root,,idx);
int t=q;
for(int i=;i<=m+q;i++)
if(query[i].times==)
continue;
else{
if(query[i].val==){
change(bccno[query[i].u],bccno[query[i].v]);
}
else{
ans[t]=sum(bccno[query[i].u],bccno[query[i].v]);
t--;
}
}
for(int i=;i<=q;i++)
printf("%d\n",ans[i]);
}
int main(){
init();
work();
}
【BZOJ】1969: [Ahoi2005]LANE 航线规划的更多相关文章
- BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )
首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键 ...
- ●BZOJ 1969 [Ahoi2005]LANE 航线规划
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1969 题解: 线段树,树链剖分,反向考虑思路是很巧妙,但是感觉代码真的恶心.. 反着考虑,先 ...
- 【刷题】BZOJ 1969 [Ahoi2005]LANE 航线规划
Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel ...
- BZOJ 1969: [Ahoi2005]LANE 航线规划 [树链剖分 时间倒流]
题意: 一张图,删除边,求两点之间的割边数量.保证任意时刻图连通 任求一棵生成树,只有树边可能是割边 时间倒流,加入一条边,就是两点路径上的边都不可能是割边,区间覆盖... 然后本题需要把边哈希一下, ...
- 【BZOJ 1969】 1969: [Ahoi2005]LANE 航线规划 (树链剖分+线段树)
1969: [Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星 ...
- 【BZOJ1969】[Ahoi2005]LANE 航线规划 离线+树链剖分+线段树
[BZOJ1969][Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由 ...
- [Ahoi2005]LANE 航线规划
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- BZOJ1969: [Ahoi2005]LANE 航线规划(LCT)
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 587 Solved: 259[Submit][Status][Discuss] Description ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
随机推荐
- JVM学习--(四)垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. stop the world 在介绍垃圾 ...
- sql语言不经常用,复习
sql语言不经常用,每次再用都隔好久的时间,以致最基本的都想不起来了,只好转一篇记着= - 找的时候方便 SQL分类: DDL-数据定义语言(CREATE,ALTER,DROP,DECLARE) ...
- Form 和 Input 对象
更改表单的 action 属性 <html> <head> <script type="text/javascript"> function c ...
- jstack Dump
jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注) 执行中,Runnable 等待资源,Waiting on conditio ...
- Python教程大纲
缘起:最近想在部门推Python语言,写这个blog主要就是个教程大纲,之前先列出一些资源:Python历史:http://www.docin.com/p-53019548.html ...
- 老司机告诉你高质量的Java代码是怎么练成的?
一提起程序员,首先想到的一定是"码农",对,我们是高产量的优质"码农",我们拥有超跃常人的逻辑思维以及不走寻常路的分析.判别能力,当然,我们也有良好的编码规范, ...
- HTML DOM innerHTML 属性及实现图片连续播放
定义和用法 innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML. 语法 tablerowObject.innerHTML=HTML 实例 下面的例子返回了表格行的 inner H ...
- JAVAEE——Mybatis第一天:入门、jdbc存在的问题、架构介绍、入门程序、Dao的开发方法、接口的动态代理方式、SqlMapConfig.xml文件说明
1. 学习计划 第一天: 1.Mybatis的介绍 2.Mybatis的入门 a) 使用jdbc操作数据库存在的问题 b) Mybatis的架构 c) Mybatis的入门程序 3.Dao的开发方法 ...
- String的split()方法可以将字符串按照特定的分隔符拆分成字符串数组
在java.lang包中有String.split()方法,返回是一个数组------不管按照什么拆,拆出来是一个数组 String str = "1,2,3,4,5,6"; St ...
- MySQL性能调优——锁定机制与锁优化分析
针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...