只有删边,想到时间倒流。

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

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
const int maxn=500010, inf=1e9;
struct poi{int too, pre;}e[maxn];
struct tjm{int sum, tag;}tree[maxn<<2];
struct qwq{int ty, x, y;}q[maxn], a[maxn];
map<ll, bool>v;
int n, m, ty, cnt, tot, tott, now;
int last[maxn], size[maxn], fa[maxn], d[maxn], son[maxn], w[maxn], top[maxn], ans[maxn];
void read(int &k)
{int f=1; k=0; char c=getchar();while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar();while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();k*=f;
}
inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
void dfs1(int x)
{size[x]=1;for(int i=last[x], too;i;i=e[i].pre){fa[too=e[i].too]=x; d[too]=d[x]+1;dfs1(too); size[x]+=size[too];if(size[too]>size[son[x]]) son[x]=too;}
}
void dfs2(int x, int tp)
{w[x]=++tott; top[x]=tp;if(son[x]) dfs2(son[x], tp);for(int i=last[x], too;i;i=e[i].pre)if((too=e[i].too)!=son[x]) dfs2(too, too);
}
inline void up(int x) {tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;}
inline void down(int x)
{if(!tree[x].tag) return;tree[x<<1].tag=1; tree[x<<1|1].tag=1;tree[x<<1].sum=tree[x<<1|1].sum=tree[x].tag=0;
}
void build(int x, int l, int r)
{if(l==r) {tree[x].sum=1; return;}int mid=(l+r)>>1;build(x<<1, l, mid); build(x<<1|1, mid+1, r);up(x);
}
void update(int x, int l, int r, int cl, int cr)
{if(cl<=l && r<=cr) {tree[x].tag=1; tree[x].sum=0; return;}down(x);int mid=(l+r)>>1;if(cl<=mid) update(x<<1, l, mid, cl, cr);if(cr>mid) update(x<<1|1, mid+1, r, cl, cr);up(x);
}
int query(int x, int l, int r, int cl, int cr)
{if(cl<=l && r<=cr) return tree[x].sum;down(x);int mid=(l+r)>>1, ans=0;if(cl<=mid) ans=query(x<<1, l, mid, cl, cr);if(cr>mid) ans+=query(x<<1|1, mid+1, r, cl, cr);return ans;
}
inline int solve(int x, int y, int ty)
{int f1=top[x], f2=top[y], ans=0;while(f1!=f2){if(d[f1]<d[f2]) swap(x, y), swap(f1, f2);if(ty) update(1, 1, n, w[f1], w[x]);else ans+=query(1, 1, n, w[f1], w[x]);x=fa[f1]; f1=top[x];}if(x==y) return ans;if(d[x]<d[y]) swap(x, y);if(ty) return update(1, 1, n, w[son[y]], w[x]), 0;return ans+query(1, 1, n, w[son[y]], w[x]);
}
int main()
{read(n); read(m);for(int i=1;i<=m;i++) {read(a[i].x); read(a[i].y);if(a[i].x>a[i].y) swap(a[i].x, a[i].y);}read(ty);while(ty!=-1){q[++cnt].ty=ty;if(ty) read(q[cnt].x), read(q[cnt].y);else {read(q[cnt].x); read(q[cnt].y);if(q[cnt].x>q[cnt].y) swap(q[cnt].x, q[cnt].y);v[1ll*q[cnt].x*66666+q[cnt].y]=1;}read(ty);}for(int i=1;i<=m && now<n-1;i++) if(!v[1ll*a[i].x*66666+a[i].y]) add(a[i].x, a[i].y), now++;dfs1(1); dfs2(1, 1); build(1, 1, n);for(int i=now+1;i<=m;i++) if(!v[1ll*a[i].x*66666+a[i].y]) solve(a[i].x, a[i].y, 1);for(int i=cnt;i;i--)if(q[i].ty) ans[++ans[0]]=solve(q[i].x, q[i].y, 0);else solve(q[i].x, q[i].y, 1);for(int i=ans[0];i;i--) printf("%d\n", ans[i]);
}

View Code

转载于:https://www.cnblogs.com/Sakits/p/8006255.html

bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)相关推荐

  1. BZOJ1969: [Ahoi2005]LANE 航线规划

    BZOJ1969: [Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由 ...

  2. 【BZOJ】1969: [Ahoi2005]LANE 航线规划

    题目链接: 传送~~ 题解:  老夫实在是码不动了-- 正着搞显然不好做,尝试倒着乱搞.先给被删除的边标记一个时间戳,先删除的时间戳大,同时维护询问时间戳,询问早的时间戳大.没被删除过的边时间戳都是0 ...

  3. BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)

    毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...

  4. 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习

    LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...

  5. 【ZJOI2008】树的统计(树链剖分)

    传送门 Solution: 就是树链剖分入门题啦~ // luogu-judger-enable-o2 #include<bits/stdc++.h> #define N 30005 #d ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. P1505 [国家集训队]旅游 树链剖分

    题目链接 题意:树上更新某一点权值,更新两点简单路径权值,查询最大,最小,和 思路:思路应该比较简单,就是树链剖分后用线段树维护区间最大最小以及区间和. 但是本题比较特殊的是给的边权,转化为点权即可. ...

  8. 【模板】树链剖分 P3384

    题目链接 //部分转自:https://www.luogu.org/problemnew/solution/P3384 初学树链剖分,感觉这个模板题还是容易理解的,但是实在是码量很大的. 知识点: 重 ...

  9. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

最新文章

  1. 中科院遗传发育所王秀杰团队鉴定出10种潜在的2019-nCoV蛋白酶抑制剂
  2. javaWeb服务详解(含源代码,测试通过,注释) ——Dept的Service层
  3. git commit报错(husky > commit-msg hook failed)
  4. Difference between Win-builds vs MinGW-builds
  5. [C/C++] C++中new的语法规则
  6. AVOD阅读笔记(二):多模型融合RPN----Aggregate View Obeject Detection network
  7. 2019年 武汉理工大学计算机考研经验分享
  8. 牛顿冷却定律--画像时间衰减系数
  9. win10开机自启动在哪里设置(Win10设置开机自启动)
  10. 国外java_Java开发必知道的国外10大网站
  11. 机器学习篇——MNIST手写数字识别
  12. 支付宝微信刷脸支付开始在全国推广
  13. uni-app - 刘海屏(Iphone X)底部横杠(——)白色区域块(安全距离处更改颜色)解决方案
  14. 人工智能学习梳理和总结
  15. js控制浏览器全屏显示
  16. android 常用短语的添加,LazyBoard – 常用短语键盘,快速输入很长的句子
  17. ES6之变量的解构赋值
  18. 异常练习(模拟不满18岁不可进入网吧)
  19. python中fig_Matplotlib画图中fig,ax,plt的区别和联系
  20. 字符编码讲解:ASCII、GB2312、GBK、Unicode、UTF-8关系

热门文章

  1. Netty之四种常用 IO 模型
  2. java多线程问题,线程交替执行
  3. Spring容器创建流程(9)完成创建
  4. java io 创建文件夹_Java中Io流操作-File类的常用操作-创建文件,创建文件夹
  5. windows安装npm教程
  6. 华为鸿蒙系统支持什么手机_什么样的手机可以刷鸿蒙系统?看看你的手机支持吗?...
  7. 如何从数据库中筛选出达成指定里程碑节点的项目_如何用共识算法构建区块链共识网络?...
  8. 软考路:2021年系统架构设计师之考试
  9. 【Elasticsearch】Elasticsearch高级调优方法论之——根治慢查询!
  10. 【Elasticsearch】Elasticsearch:Elasticsearch中的refresh和flush操作指南