bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)
只有删边,想到时间倒流。
倒着加边,因为保证图连通,所以一开始一定至少是一棵树。我们先建一棵树出来,对于每一条非树边,两个端点在树上这段路径的边就不会变成关键边了,所以将它们对答案的贡献删去,那么直接树链剖分就好了。
#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 航线规划(树链剖分)相关推荐
- BZOJ1969: [Ahoi2005]LANE 航线规划
BZOJ1969: [Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由 ...
- 【BZOJ】1969: [Ahoi2005]LANE 航线规划
题目链接: 传送~~ 题解: 老夫实在是码不动了-- 正着搞显然不好做,尝试倒着乱搞.先给被删除的边标记一个时间戳,先删除的时间戳大,同时维护询问时间戳,询问早的时间戳大.没被删除过的边时间戳都是0 ...
- BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)
毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...
- 对LCA、树上倍增、树链剖分(重链剖分长链剖分)和LCT(Link-Cut Tree)的学习
LCA what is LCA & what can LCA do LCA(Lowest Common Ancestors),即最近公共祖先 在一棵树上,两个节点的深度最浅的公共祖先就是 L ...
- 【ZJOI2008】树的统计(树链剖分)
传送门 Solution: 就是树链剖分入门题啦~ // luogu-judger-enable-o2 #include<bits/stdc++.h> #define N 30005 #d ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- P1505 [国家集训队]旅游 树链剖分
题目链接 题意:树上更新某一点权值,更新两点简单路径权值,查询最大,最小,和 思路:思路应该比较简单,就是树链剖分后用线段树维护区间最大最小以及区间和. 但是本题比较特殊的是给的边权,转化为点权即可. ...
- 【模板】树链剖分 P3384
题目链接 //部分转自:https://www.luogu.org/problemnew/solution/P3384 初学树链剖分,感觉这个模板题还是容易理解的,但是实在是码量很大的. 知识点: 重 ...
- 树链剖分——线段树区间合并bzoj染色
线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...
最新文章
- 中科院遗传发育所王秀杰团队鉴定出10种潜在的2019-nCoV蛋白酶抑制剂
- javaWeb服务详解(含源代码,测试通过,注释) ——Dept的Service层
- git commit报错(husky > commit-msg hook failed)
- Difference between Win-builds vs MinGW-builds
- [C/C++] C++中new的语法规则
- AVOD阅读笔记(二):多模型融合RPN----Aggregate View Obeject Detection network
- 2019年 武汉理工大学计算机考研经验分享
- 牛顿冷却定律--画像时间衰减系数
- win10开机自启动在哪里设置(Win10设置开机自启动)
- 国外java_Java开发必知道的国外10大网站
- 机器学习篇——MNIST手写数字识别
- 支付宝微信刷脸支付开始在全国推广
- uni-app - 刘海屏(Iphone X)底部横杠(——)白色区域块(安全距离处更改颜色)解决方案
- 人工智能学习梳理和总结
- js控制浏览器全屏显示
- android 常用短语的添加,LazyBoard – 常用短语键盘,快速输入很长的句子
- ES6之变量的解构赋值
- 异常练习(模拟不满18岁不可进入网吧)
- python中fig_Matplotlib画图中fig,ax,plt的区别和联系
- 字符编码讲解:ASCII、GB2312、GBK、Unicode、UTF-8关系
热门文章
- Netty之四种常用 IO 模型
- java多线程问题,线程交替执行
- Spring容器创建流程(9)完成创建
- java io 创建文件夹_Java中Io流操作-File类的常用操作-创建文件,创建文件夹
- windows安装npm教程
- 华为鸿蒙系统支持什么手机_什么样的手机可以刷鸿蒙系统?看看你的手机支持吗?...
- 如何从数据库中筛选出达成指定里程碑节点的项目_如何用共识算法构建区块链共识网络?...
- 软考路:2021年系统架构设计师之考试
- 【Elasticsearch】Elasticsearch高级调优方法论之——根治慢查询!
- 【Elasticsearch】Elasticsearch:Elasticsearch中的refresh和flush操作指南