线段树分治

其实思想说起来是比较简单的,我们把这个题里的所有操作(比如连边删边查询balabala)全部拍到一棵线段树上,然后对着整棵树dfs一下求解答案,顺便把操作做一下,回溯的时候撤销一下即可。虽然有的操作需要以区间形式拍到树上,导致它可能会被拆成两个,但线段树的形态同样保证了操作最多只会被拆分\(log(区间长度)\)次,保障了复杂度。

洛谷P5227[AHOI2013]连通图

传送门

其实就是线段树分治+带撤销并查集,并查集写按秩合并,不能路径压缩(否则会破坏结构,就会撤销出奇怪的效果)

以询问的时间轴为下标建一棵线段树,然后把边存在的时间区间拍到线段树上,用\(vector\)存下来,再对着树一波\(dfs\)记录答案,注意在叶节点不能写\(return\)我沙茶了,不然叶节点如果有操作就会还没撤销就返回了。

md没有板对着敲自己yy着写好难受,码了一天

/*P5227 [AHOI2013]连通图*/
#include <bits/stdc++.h>
#define N (100000 + 5)
using namespace std;
inline int read() {
int cnt = 0, f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
return cnt * f;
}
int n, m, k, c, x, top;
int fa[N];
struct node {
int u, v;
}edge[N << 1];
struct node2 {
int siz, dep, fa;
node2(int siz_ = 1, int dep_ = 1, int fa_ = 0) : siz(siz_), dep(dep_), fa(fa_){};
}bcj[N << 1], ctrl_Z[N << 1];
int cur[N << 1], top2;
int pre[N << 1];
int get_father(int x) {return x == bcj[x].fa ? x : get_father(bcj[x].fa);}
void merge(int p, int q) {
int x = get_father(p), y = get_father(q);
if (x == y) return;
if (bcj[x].dep > bcj[y].dep) swap(x, y);
ctrl_Z[++top] = bcj[x];
ctrl_Z[++top] = bcj[y];
bcj[x].fa = y, bcj[y].dep = max(bcj[y].dep, bcj[x].dep + 1), bcj[y].siz += bcj[x].siz;
cur[++top2] = x;
cur[++top2] = y;
}
struct node3{
int l, r;
vector<node> E;
#define l(p) tree[p].l
#define r(p) tree[p].r
}tree[N << 2]; void build(int l, int r, int p) {
l(p) = l, r(p) = r;
if (l == r) return;
int mid = (l + r) >> 1;
build (l, mid, p << 1);
build (mid + 1, r, p << 1 | 1);
} void insert(node x, int l, int r, int p) {
if (l <= l(p) && r >= r(p)) { tree[p].E.push_back(x); return; }
register int mid = (l(p) + r(p)) >> 1;
if (l <= mid) insert(x, l, r, p << 1);
if (r > mid) insert(x, l, r, p << 1 | 1);
}
void dfs_(int p) {
int tp = top2;
for (register unsigned int i = 0; i < tree[p].E.size(); i++) {
node now = tree[p].E[i];
merge(now.u, now.v);
}
if (l(p) == r(p)) {
int now = bcj[get_father(1)].siz;
printf(now == n ? "Connected\n" : "Disconnected\n");
} else dfs_(p << 1), dfs_(p << 1 | 1);
for (; top2 > tp; --top2, --top) {bcj[cur[top2]] = ctrl_Z[top];}
} int main() {
n = read(), m = read();
for (register int i = 1; i <= n; i++) bcj[i] = node2(1, 1, i);
for (register int i = 1; i <= m; i++)
edge[i].u = read(), edge[i].v = read(), pre[i] = 1;
k = read();
build (1, k, 1);
for (register int i = 1; i <= k; i++) {
c = read();
for (register int j = 1; j <= c; j++) {
x = read();
if (pre[x] < i) insert(edge[x], pre[x], i - 1, 1);
pre[x] = i + 1;
}
}
for (register int i = 1; i <= m; i++) {
if (pre[i] <= k) insert(edge[i], pre[i], k, 1);
}
dfs_(1);
return 0;
}

线段树分治初步学习&洛谷P5227[AHOI2013]连通图的更多相关文章

  1. 李超线段树(segment[HEOI2013]-洛谷T4097)

    (neng了好久好久才糊弄懂得知识点...) 一.李超线段树 在线动态维护一个二维平面直角坐标系, 支持插入一条线段, 询问与直线x = x0相交的所有线段中,交点y的最大/小值 (若有多条线段符合条 ...

  2. 线段树板子1(洛谷P3372)

    传送 一道线段树板子(最简单的) 似乎之前在培训里写过线段树的样子?不记得了 何为线段树? 一般就是长成这样的树,树上的每个节点代表一个区间.线段树一般用于区间修改,区间查询的问题. 我们如何种写一棵 ...

  3. 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)

    LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...

  4. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  5. 【洛谷4219】[BJOI2014]大融合(线段树分治)

    题目: 洛谷4219 分析: 很明显,查询的是删掉某条边后两端点所在连通块大小的乘积. 有加边和删边,想到LCT.但是我不会用LCT查连通块大小啊.果断弃了 有加边和删边,还跟连通性有关,于是开始yy ...

  6. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  7. 洛谷 P2147 [SDOI2008]洞穴勘测 (线段树分治)

    题目链接 题解 早就想写线段树分治的题了. 对于每条边,它存在于一段时间 我们按时间来搞 我们可把一条边看做一条线段 我们可以模拟线段树操作,不断分治下去 把覆盖\(l-r\)这段时间的线段筛选出来, ...

  8. 【洛谷4585】[FJOI2015] 火星商店问题(线段树分治)

    点此看题面 大致题意: 有\(n\)家店,每个商品有一个标价.每天,都可能有某家商店进货,也可能有某人去购物.一个人在购物时,会于编号在区间\([L_i,R_i]\)的商店里挑选一件进货\(d_i\) ...

  9. 【洛谷P4319】 变化的道路 线段树分治+LCT

    最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...

随机推荐

  1. postgresql+java数据类型对照

    网上搜了很多都不理想,这里总结的一部分是官网的文档,一部分是网上的,大体没问题 PostgreSQL™                 Java SE 8 date            LocalD ...

  2. Java 核心编程技术干货,2019 最新整理版!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新. Java 基础篇 ...

  3. Vagrant安装步骤

    Vagrant安装步骤 下载添加box镜像 vagrant box add base 远端的box地址或者本地的box文件名 建立box镜像关联 vagrant box add centos72 va ...

  4. 360自动抢票还不够,几行js代码设置无人值守

    360就是牛逼哄哄的...... 但是最近在使用360浏览器抢票的时候还是发现了一些体验不好的地方,比如搞着搞着就退出了登录,有时候能帮你自动登录进去,但是自动登录之后又不会帮你自动开始抢.然后验证码 ...

  5. 关于 第三方接口支付的时候 采用post提交的方式,有两种 一种是通过 curl来进行,一种是通过js当页面加载完后跳转

    这是第一种.通过javascript页面加载完后,对表单采用 post方式提交给 第三方接口----- echo <<<_END<!DOCTYPE html PUBLIC &q ...

  6. windows 嵌入控制台

    { 实际非常简单 需要控制台的hwnd 和 hdc 能获取控制台的hwnd 那hdc 就出来了 有了hdc 还有什么不能干的呢?? 如果会win32 窗口编程的就知道hdc,是一个让人流口水的类型 } ...

  7. JS调用C++

    1.注册C++函数. //注册回调函数宏 //根据不同需要支持注册两个函数原型,注意CONNECT_JS_CALL_SIMPLE_HANDLER中注册的函数 //需要提前和HTML调用协调好,参数必须 ...

  8. 精度试验结果报告Sleep, GetTickCount, timeGetTime, QueryPerformanceCounter

    一段简单的代码来实现精度试验 int main() {       // 初始化代码       ......       int i = 0;       while(i++ < 1000) ...

  9. 数据可视化(matplotilb)

    一,matplotilb库(数学绘图库) mat数学 plot绘图  lib库 matplotlib.pyplot(缩写mp)->python 最常用接口 mp.plot(水平坐标,垂直坐标数组 ...

  10. P1280 尼克的任务 /// DP(选择性地)

    题目大意: https://www.luogu.org/problemnew/show/P1280 题解 手推一遍思路更清晰 #include <bits/stdc++.h> using ...