题解:

cf765f

cf671e

bzoj4184

bzoj4552

线段树分治裸题

还是介绍一下线段树分治

这个东西其实挺简单但也挺有用的

可以把删除+插入操作变成只有插入(倒着就是删除)

像这一道题,我们对时间点建立线段树

对一段区间共同有的元素依次加入到线段树中(开个队列维护一下)

发现这样是只有nlogn个点

另外这个标记显然是可以标记永久化的

apio t1是这个所以就学习了一下

为了练习一下可持久化并查集于是我就写了

然后主席树造成了它一定会mle。。nlognlog(nlogn)

其实只用带撤销的并查集就可以了

#include <bits/stdc++.h>
using namespace std;
const int N=4e7+;
const int N2=3e5+;
struct re{
int x,y;
}a[N2];
int cnt,now,n,m,k;
int ls[N],rs[N],data[N];
int ph[N2*],pt[N2*],count2[N2],f[N2];
bool ft[N2];
vector<int> ve[N2*];
#define mid (ph[x]+pt[x])/2
void change(int last,int &now,int h,int t,int goal,int goal2)
{
now=++cnt;
if (h==t)
{
data[now]=goal2;
return;
}
ls[now]=ls[last];
rs[now]=rs[last];
int mid2=(h+t)/;
if (goal<=mid2) change(ls[last],ls[now],h,mid2,goal,goal2);
else change(rs[last],rs[now],mid2+,t,goal,goal2);
}
int query(int x,int h,int t,int goal)
{
if (h==t) return(data[x]);
int mid2=(h+t)/;
if (goal<=mid2) return(query(ls[x],h,mid2,goal));
else return(query(rs[x],mid2+,t,goal));
}
void build(int x,int h,int t)
{
ph[x]=h; pt[x]=t;
if (h==t) return;
build(x*,h,mid); build(x*+,mid+,t);
}
void insert(int x,int h,int t,int goal)
{
if (h<=ph[x]&&pt[x]<=t)
{
ve[x].push_back(goal);
return;
}
if (h<=mid) insert(x*,h,t,goal);
if (mid<t) insert(x*+,h,t,goal);
}
int find(int root,int x)
{
int y=query(root,,N,x);
if (y==x) return(x);
else return(find(root,y));
}
void dfs(int x,int h,int t,int ans)
{
stack<re> s;
int now1=now;
int len=ve[x].size();
for (int i=;i<len;i++)
{
int x1=a[ve[x][i]].x,x2=a[ve[x][i]].y;
int x11=find(now,x1),x22=find(now,x2);
if (x11!=x22)
{
if (count2[x11]>count2[x22]) swap(x11,x22);
change(now,now,,N,x11,x22);
s.push(re{x22,count2[x22]});
count2[x22]+=count2[x11];
ans++;
}
}
if (h==t)
{
if (ans==n-) ft[h]=; else ft[h]=;
} else
{
dfs(x*,h,(h+t)/,ans);
dfs(x*+,(h+t)/+,t,ans);
}
while (!s.empty())
{
re x=s.top(); s.pop();
count2[x.x]=x.y;
}
now=now1;
}
int main()
{
freopen("3237.in","r",stdin);
freopen("3237.out","w",stdout);
cin>>n>>m;
for (int i=;i<=m;i++)
{
cin>>a[i].x>>a[i].y;
}
cin>>k;
for (int i=;i<=n;i++) f[i]=;
for (int i=;i<=n;i++)
{
change(now,now,,N,i,i);
count2[i]=;
}
build(,,k);
for (int i=;i<=k;i++)
{
int nown,x;
cin>>nown;
for (int j=;j<=nown;j++)
{
cin>>x;
if (i->=f[x])
{
insert(,f[x],i-,x);
}
f[x]=i+;
}
}
for (int i=;i<=m;i++)
if (f[i]<=k)
insert(,f[i],k,i);
dfs(,,k,);
for (int i=;i<=k;i++)
if (ft[i]==) cout<<"Connected"<<endl;
else cout<<"Disconnected"<<endl;
return ;
}

这个是正确的

#include <bits/stdc++.h>

using namespace std;

const int N=4e7+;

const int N2=3e5+;
#define rint register int
struct re{ int x,y,z; }a[N2];
char ss[<<],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;}
template<class T>void read(T&x){
rint f=,c;while(c=gc(),c<||<c)if(c=='-')f=-;x=c^;
while(c=gc(),<c&&c<)x=(x<<)+(x<<)+(c^);x*=f;
}
int cnt,now,n,m,k; int ph[N2*],pt[N2*],fa[N2],count2[N2],f[N2]; bool ft[N2]; vector<int> ve[N2*]; #define mid (ph[x]+pt[x])/2 void build(int x,int h,int t) { ph[x]=h; pt[x]=t; if (h==t) return; build(x*,h,mid); build(x*+,mid+,t); } void insert(int x,int h,int t,int goal) { if (h<=ph[x]&&pt[x]<=t) { ve[x].push_back(goal); return; } if (h<=mid) insert(x*,h,t,goal); if (mid<t) insert(x*+,h,t,goal); } int find(int x) { int y=fa[x]; if (y==x) return(x); else return(find(y)); } void dfs(int x,int h,int t,int ans) { stack<re> s; int now1=now; int len=ve[x].size(); for (int i=;i<len;i++) { int x1=a[ve[x][i]].x,x2=a[ve[x][i]].y; int x11=find(x1),x22=find(x2); if (x11!=x22) { if (count2[x11]>count2[x22]) swap(x11,x22); fa[x11]=x22; s.push(re{x22,count2[x22],x11}); count2[x22]+=count2[x11]; ans++; } } if (h==t) { if (ans==n-) ft[h]=; else ft[h]=; } else { dfs(x*,h,(h+t)/,ans); dfs(x*+,(h+t)/+,t,ans); } while (!s.empty()) { re x=s.top(); s.pop(); count2[x.x]=x.y;
fa[x.z]=x.z; } now=now1; } int main() { freopen("3237.in","r",stdin); freopen("3237.out","w",stdout); read(n); read(m); for (int i=;i<=m;i++) { read(a[i].x); read(a[i].y);
} read(k); for (int i=;i<=n;i++) f[i]=; for (int i=;i<=n;i++) { fa[i]=i; count2[i]=; } build(,,k); for (int i=;i<=k;i++) { int nown,x; read(nown); for (int j=;j<=nown;j++) { read(x); if (i->=f[x]) { insert(,f[x],i-,x); } f[x]=i+; } } for (int i=;i<=m;i++) if (f[i]<=k) insert(,f[i],k,i); dfs(,,k,); for (int i=;i<=k;i++) if (ft[i]==) puts("Connected"); else puts("Disconnected"); return ; }

3237: [Ahoi2013]连通图 线段树分治的更多相关文章

  1. BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)

    Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...

  2. 线段树分治初步学习&洛谷P5227[AHOI2013]连通图

    线段树分治 其实思想说起来是比较简单的,我们把这个题里的所有操作(比如连边删边查询balabala)全部拍到一棵线段树上,然后对着整棵树dfs一下求解答案,顺便把操作做一下,回溯的时候撤销一下即可.虽 ...

  3. 【线段树分治】【P5227】 [AHOI2013]连通图

    Description 给定一个无向连通图和若干个小集合,每个小集合包含一些边,对于每个集合,你需要确定将集合中的边删掉后改图是否保持联通.集合间的询问相互独立 定义一个图为联通的当且仅当对于任意的两 ...

  4. BZOJ3237 AHOI2013连通图(线段树分治+并查集)

    把查询看做是在一条时间轴上.那么每条边都有几段存在时间.于是线段树分治就好了. 然而在bzoj上t掉了,不知道是常数大了还是写挂了. 以及brk不知道是啥做数组名过不了编译. #include< ...

  5. 线段树分治总结(线段树分治,线段树,并查集,树的dfn序,二分图染色)

    闲话 stO猫锟学长,满脑子神仙DS 网上有不少Dalao把线段树分治也归入CDQ分治? 还是听听YCB巨佬的介绍: 狭义:只计算左边对右边的贡献. 广义:只计算外部对内部的贡献. 看来可以理解为广义 ...

  6. BZOJ 3237: [Ahoi2013]连通图

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1161  Solved: 399[Submit][Status ...

  7. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  8. LOJ2312 LUOGU-P3733「HAOI2017」八纵八横 (异或线性基、生成树、线段树分治)

    八纵八横 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路的两端都是城市(可能两端是同一个 ...

  9. BZOJ 3237([Ahoi2013]连通图-cdq图重构-连通性缩点)

    3237: [Ahoi2013]连通图 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 106   Solved: 31 [ Submit][ St ...

随机推荐

  1. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

  2. java AOP使用配置项来进行注入实践

    java AOP使用注解@annotation方式实践 场景: 在目标方法前面和后面执行通知方法 目标类 @Component public class Play { public void watc ...

  3. IIC AT24C02读写数据的一点小体会

    一.写数据 unsigned char I2CWriteByte(unsigned int mem_addr,unsigned char*DDATAp,unsigned int count) { u8 ...

  4. MyBatis参数传递

    一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...

  5. centOS7安装Composer

    1.进入Composer国内镜像网站文档页查看安装方法: https://docs.phpcomposer.com/00-intro.html 2.在centOS系统中进入特定目录执行以下命令: cd ...

  6. VS2012 安装番茄插件

    1.visual assist x 1929_大番茄.rar 下载地址: http://pan.baidu.com/s/1qXOUuJE 网盘提取密码: 3mka 文件解压密码: eg5p 2.安装完 ...

  7. JS获取今天和上个月的今天

    function getLastMonth(){ var now=new Date(); var year = now.getFullYear();//getYear()+1900=getFullYe ...

  8. Bootstrap2.x与Bootstrap3.x的区别

    做项目时,有时也会参考别的案例的优秀之处.在用Bootstrap的时候,发现很多项目代码都有区别,在<div>布局class上,有用.span*,有用.col-md-*,实际上是Boots ...

  9. 四、Logisitic Regssion练习(转载)

    转载:http://www.cnblogs.com/tornadomeet/archive/2013/03/16/2963919.html 牛顿法:http://blog.csdn.net/xp215 ...

  10. 在Asp.Net Core中使用中间件保护非公开文件

    在企业开发中,我们经常会遇到由用户上传文件的场景,比如某OA系统中,由用户填写某表单并上传身份证,由身份管理员审查,超级管理员可以查看. 就这样一个场景,用户上传的文件只能有三种人看得见(能够访问) ...