以下这个做法应该是叫线段树分治。。。

根据修改操作预处理出每条边存在的时间区间[l,r](以操作序号为时间),然后把所有形式化后的修改挂到线段树节点上。

处理完修改后,dfs一遍线段树,进入某个节点时把那个点上所有的修改操作做一遍连边(用按秩合并并查集),出来时再撤销那些连边;那么到达叶节点时,刚好就是完成了这个节点代表的时间所需要的一切修改操作

复杂度O(nlog^2n),比lct要大

这个东西跟cdq分治一样是时间分治,但是好像不能降维的样子(?反正想了很久没想通),不过能在有些有加入、删除、查询操作的题中,把删除操作规避掉

以下代码把线段树避免掉了(其实是处理过程中把树建出来。。。)

 #include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#define pb push_back
using namespace std;
struct Info
{
int fx,fy,dx,dy;
}ttt[];
int tlen;
struct Q
{
bool type;
int l,r,a,b;
};
bool ans[];
int qnum,n,m;
char tmp[];
map<int,int> ma[];
map<int,int>::iterator it;
int fa[],dep[];
int find(int x)
{
for(;x!=fa[x];x=fa[x]);
return x;
}
void add(const Q &x)
{
int fx=find(x.a),fy=find(x.b);++tlen;
ttt[tlen].fx=fx;ttt[tlen].fy=fy;
ttt[tlen].dx=dep[fx];ttt[tlen].dy=dep[fy];
if(dep[fx]>dep[fy]) fa[fy]=fx;
else
{
fa[fx]=fy;
if(dep[fx]==dep[fy]) dep[fy]++;
}
}
void del(int tm)
{
for(int i=,fx,fy;i<=tm;i++)
{
fx=ttt[tlen].fx;fy=ttt[tlen].fy;
fa[fx]=fx;fa[fy]=fy;
dep[fx]=ttt[tlen].dx;dep[fy]=ttt[tlen].dy;
--tlen;
}
}
void solve(const vector<Q> &q,int l,int r)
//当前线段树上区间为[l,r],要处理的询问为q
{
int i,nn=,sz=q.size();
if(l==r)
{
for(i=;i<sz;i++)
if(q[i].type==)
add(q[i]),++nn;
for(i=;i<sz;i++)
if(q[i].type==)
ans[l]=find(q[i].a)==find(q[i].b);
del(nn);
return;
}
int mid=l+(r-l)/;vector<Q> qq1,qq2;
for(i=;i<sz;i++)
{
if(q[i].type==)
{
if(q[i].l<=l&&r<=q[i].r) add(q[i]),++nn;
else
{
if(q[i].l<=mid) qq1.push_back(q[i]);
if(mid<q[i].r) qq2.push_back(q[i]);
}
}
else
{
if(q[i].l<=mid) qq1.pb(q[i]);
else qq2.pb(q[i]);
}
}
solve(qq1,l,mid);
solve(qq2,mid+,r);
del(nn);
}
vector<Q> q;
bool type[];
int main()
{
int i,a,b;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) fa[i]=i;
for(i=;i<=m;i++)
{
scanf("%s%d%d",tmp,&a,&b);if(a>b) swap(a,b);
if(tmp[]=='Q') q.pb((Q){,i,,a,b}),type[i]=;
else if(tmp[]=='C') ma[a][b]=i;
else if(tmp[]=='D') q.pb((Q){,ma[a][b],i,a,b}),ma[a].erase(b);
}
for(i=;i<=n;i++)
for(it=ma[i].begin();it!=ma[i].end();it++)
q.pb((Q){,it->second,m,i,it->first});
solve(q,,m);
for(i=;i<=m;i++)
if(type[i]==)
puts(ans[i]?"Yes":"No");
return ;
}

洛谷 P2147 [SDOI2008]洞穴勘测的更多相关文章

  1. 洛谷P2147[SDOI2008]洞穴勘测(lct)

    题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...

  2. [洛谷P2147][SDOI2008]洞穴勘测

    题目大意:有$n$个洞穴,$m$条指令,指令有三种 $Connect\;u\;v$:在$u,v$之间连一条边 $Destroy\;u\;v$:切断$u,v$之间的边 $Query\;u\;v$:询问$ ...

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

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

  4. 洛谷 P2147 [SDOI2008]洞穴勘测 LCT

    Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...

  5. 洛谷P2147 [SDOI2008] 洞穴勘探 [LCT]

    题目传送门 洞穴勘探 题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道 ...

  6. 【洛谷P2147】洞穴勘测

    题目大意:维护 N 个点的无向图,支持动态加边和删边,回答两点的连通性. 题解:线段树分治 + 可撤销并查集 询问可以离线,这是线段树分治的基础. 建立在操作时间轴上的线段树称为线段树分治算法. 本题 ...

  7. P2147 [SDOI2008]洞穴勘测(LCT)

    P2147 [SDOI2008]洞穴勘测 裸的LCT. #include<iostream> #include<cstdio> #include<cstring> ...

  8. P2147 [SDOI2008]洞穴勘测

    P2147 [SDOI2008]洞穴勘测 思路 没办法,我就是喜欢板子都想发的人 都是基础操作,不多说了 代码 #include <bits/stdc++.h> #define ls ch ...

  9. 洛谷P2147 [SDOI2008]Cave 洞穴勘测

    题目描述 辉辉热衷于洞穴勘测. 某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假 ...

随机推荐

  1. Jenkins+appium+testng持续集成

    Create maven project in eclipseAdd Appium , Selenium dependancyAdd Test in TestNG testCreate TestNG ...

  2. CentOS笔记-目录结构(转载了菜鸟教程里的)

    在linux系统中,有几个目录是比较重要的,平时需要注意不要误删除或者随意更改内部文件. /etc: 上边也提到了,这个是系统中的配置文件,如果你更改了该目录下的某个文件可能会导致系统不能启动. /b ...

  3. 关于java赋值操作的原子性问题

    17.7. Non-Atomic Treatment of double and long For the purposes of the Java programming language memo ...

  4. 大O符号

    大O 就是 时间复杂度.时间复杂度是大概的描述一个算法的用时(实际上从侧面的表达了他的效率) 最好时间复杂度,通常指在最好情形下,这个算法用时.反之,最坏情况下的就是最坏时间复杂度.通常 冒泡算法 的 ...

  5. vfork函数的使用【学习笔记】

    #include "apue.h" ; int main(void) { int var; pid_t pid; ; printf("before vfork\r\n&q ...

  6. POJ3273 Monthly Expense —— 二分

    题目链接:http://poj.org/problem?id=3273   Monthly Expense Time Limit: 2000MS   Memory Limit: 65536K Tota ...

  7. .Net线程池ThreadPool导致内存高的问题分析

    最近写了一个WinFrom程序.此程序侦听TCP端口,接受消息处理,然后再把处理后的消息,利用线程池通过WebService发送出去(即一进一出). 在程序编写完成后,进行压力测试.用Fiddler提 ...

  8. JAVASCRIPT技术 表达式验证

    失去焦点时,调用方法: <html> <head><script type="text/javascript">function upperCa ...

  9. linux静默安装Oracle 11g

    ./runInstaller -silent -force -responseFile /home/oracle/software/database/response/orcl_install.rsp ...

  10. 书写优雅的shell脚本(二)- `dirname $0`

    在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".". 这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个 ...