题解:

cf765f

cf671e

bzoj4184

bzoj4552

线段树分治裸题

还是介绍一下线段树分治

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

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

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

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

发现这样是只有nlogn个点

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

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

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

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

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

#include <bits/stdc++.h>
using namespace std;
const int N=4e7+10;
const int N2=3e5+10;
struct re{int x,y;
}a[N2];
int cnt,now,n,m,k;
int ls[N],rs[N],data[N];
int ph[N2*4],pt[N2*4],count2[N2],f[N2];
bool ft[N2];
vector<int> ve[N2*4];
#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)/2;if (goal<=mid2) change(ls[last],ls[now],h,mid2,goal,goal2);else change(rs[last],rs[now],mid2+1,t,goal,goal2);
}
int query(int x,int h,int t,int goal)
{if (h==t) return(data[x]);int mid2=(h+t)/2;if (goal<=mid2) return(query(ls[x],h,mid2,goal));else return(query(rs[x],mid2+1,t,goal));
}
void build(int x,int h,int t)
{ph[x]=h; pt[x]=t;if (h==t) return;build(x*2,h,mid); build(x*2+1,mid+1,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*2,h,t,goal);if (mid<t) insert(x*2+1,h,t,goal);
}
int find(int root,int x)
{int y=query(root,1,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=0;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,1,N,x11,x22);s.push(re{x22,count2[x22]});count2[x22]+=count2[x11];ans++;}}if (h==t){if (ans==n-1) ft[h]=1; else ft[h]=0;} else{dfs(x*2,h,(h+t)/2,ans); dfs(x*2+1,(h+t)/2+1,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=1;i<=m;i++){cin>>a[i].x>>a[i].y;}cin>>k;for (int i=1;i<=n;i++) f[i]=1;for (int i=1;i<=n;i++){change(now,now,1,N,i,i);count2[i]=1;}build(1,1,k);for (int i=1;i<=k;i++){int nown,x;cin>>nown;for (int j=1;j<=nown;j++){cin>>x;if (i-1>=f[x]){insert(1,f[x],i-1,x);}f[x]=i+1;}}for (int i=1;i<=m;i++)if (f[i]<=k)insert(1,f[i],k,i);dfs(1,1,k,0);for (int i=1;i<=k;i++)if (ft[i]==1) cout<<"Connected"<<endl;else cout<<"Disconnected"<<endl;return 0;
}

这个是正确的

#include <bits/stdc++.h>using namespace std;const int N=4e7+10;const int N2=3e5+10;
#define rint register int
struct re{int x,y,z;}a[N2];
char ss[1<<24],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;}
template<class T>void read(T&x){rint f=1,c;while(c=gc(),c<48||57<c)if(c=='-')f=-1;x=c^48;while(c=gc(),47<c&&c<58)x=(x<<3)+(x<<1)+(c^48);x*=f;
}
int cnt,now,n,m,k;int ph[N2*4],pt[N2*4],fa[N2],count2[N2],f[N2];bool ft[N2];vector<int> ve[N2*4];#define mid (ph[x]+pt[x])/2void build(int x,int h,int t){ph[x]=h; pt[x]=t;if (h==t) return;build(x*2,h,mid); build(x*2+1,mid+1,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*2,h,t,goal);if (mid<t) insert(x*2+1,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=0;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-1) ft[h]=1; else ft[h]=0;} else{dfs(x*2,h,(h+t)/2,ans); dfs(x*2+1,(h+t)/2+1,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=1;i<=m;i++){read(a[i].x); read(a[i].y);}read(k);for (int i=1;i<=n;i++) f[i]=1;for (int i=1;i<=n;i++){fa[i]=i;count2[i]=1;}build(1,1,k);for (int i=1;i<=k;i++){int nown,x;read(nown);for (int j=1;j<=nown;j++){read(x);if (i-1>=f[x]){insert(1,f[x],i-1,x);}f[x]=i+1;}}for (int i=1;i<=m;i++)if (f[i]<=k)insert(1,f[i],k,i);dfs(1,1,k,0);for (int i=1;i<=k;i++)if (ft[i]==1) puts("Connected");else puts("Disconnected");return 0;}

转载于:https://www.cnblogs.com/yinwuxiao/p/9038629.html

3237: [Ahoi2013]连通图 线段树分治相关推荐

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

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

  2. BZOJ 3237: [Ahoi2013]连通图

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

  3. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  4. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  5. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  6. LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治...

    题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...

  7. CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)

    题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...

  8. 牛客多校8 - All-Star Game(线段树分治+并查集按秩合并的撤销操作)

    题目链接:点击查看 题目大意:有 n 个球员和 m 个球迷,一个球员可能是多个球迷的粉丝,需要选择最少的球员进行比赛,使得所有的球迷都愿意观看(对于每个球迷来说,都有至少一个其喜欢的球员入选比赛) 对 ...

  9. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

最新文章

  1. 【组队学习】【35期】吃瓜教程——西瓜书+南瓜书
  2. asp.net中GridView传多个值到其它页面的方法
  3. centos 开机启动java_java程序在centos7里面开机自启动
  4. 启动欢迎页面时,Android Studio设置全屏Activity
  5. python中for和while区别_Python学习第九篇——while和for的区别
  6. 新的吉尼斯世界纪录 – 最快人类基因组测序,用时5 小时 2 分钟!
  7. 求整数的位数及各位数字之和 (15 分)
  8. python_day29_通过类创建多线程_队列
  9. Open vSwitch流表应用实战
  10. ios键盘横屏_平板电脑就只能追剧玩游戏?看这款外设键盘如何让iPad爱上办公...
  11. 3700打印机和计算机连接,WNDR3700成功实现打印机服务器功能(刷机成WNDR3800)
  12. 工作总结 @{var sas = String.Format({0:yyyy-MM-dd}, Model.DemandTime.GetValueOrDefault());}
  13. 程序员求职之道(《程序员面试笔试宝典》)之民间的企业排名的可信度到底有多大?...
  14. 模电:集成运算放大器
  15. Java 2.2(计算圆柱的体积)编写程序,读入圆柱体的半径和高,并使用下列公式计算圆柱体的体积:
  16. 1.7-工控上位机软件开发平台介绍
  17. 弦截法及Python实现
  18. 浅谈对象的深拷贝和浅拷贝
  19. Youtube2016推荐召回算法细节及最终实现(离线服务)——完整版
  20. 【工作流】工作流快速入门

热门文章

  1. 深度学习在智能助理中的应用
  2. 以太坊虚拟机EVM的缺陷与不足
  3. Android Framework------之Keyguard 简单分析
  4. TensorFlow-CIFAR10 CNN代码分析
  5. Sparkmllib scala svm demo
  6. android 自定义banner,Android项目 引入Banner开源库(轮播图)
  7. c语言作业指导1,C语言程序设计实验与习题指导
  8. latex 引用_VS Code + LaTex + Zotero 写作毕业论文
  9. [转载]我的博后申请经历从陶瓷到Offer过程
  10. 极大似然估计的直观解释-转