博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3295 [SCOI2016]萌萌哒
阅读量:5255 次
发布时间:2019-06-14

本文共 1240 字,大约阅读时间需要 4 分钟。

  真的好久好久没写题解啦……真是不好意思!

  emmm……立刻岔开话题……

  这道题真的是一道很好很好的倍增优化并查集的题!

  首先对于暴力,就是每一个点都暴力并查集,每一次判断这个点的祖先是不是自己就可以了,30分。

  我么当然不能止步于30分啊,所以自然要想想优化啦!

  我一开始是想单独考虑每一个子问题,考虑这段区间是否包含原来修改的部分,但是发现需要维护的东西太多了……不能简单明了的解决问题。

  再回头看看题面,我们由于不能每一次都一个个地维护每一个点的并查集,就想到了倍增优化。

  对于状态 fa [ i ] [ j ] 意思是从 i 开始 2- 1 的长度,i 的父亲是谁(和 i 相同的区间左端点)。 那么我们只要将这段区间拆成若干个(logn)个子区间,再一一对应维护并查集即可。

  由于我们最后是要小的状态 fa [ i ] [ 0 ],所以对于一个区间的父亲,我们再分别将父亲的状态分开再转给儿子,就保证了最后能维护到最短的这个区间(长度为1,fa [ x ] [ 0 ] )。

  最后统计独立点个数就行。

  代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;#define maxn 100005#define int long longconst int mod = 1e9+7;int fa[maxn][25];int n,m;int find(int x,int i){ return x == fa[x][i] ? x : fa[x][i] = find(fa[x][i],i);}void merge(int x,int y,int i){ x=find(x,i); y=find(y,i); if(x!=y) fa[x][i]=y;}main(){ int ans=9; scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) for(int j=0;j<=20;j++) fa[i][j]=i; for(int i=1;i<=m;i++) { int l1,r1,l2,r2; scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2); for(int j=20;j>=0;j--) { if(l1+(1<
<=r1) { merge(l1,l2,j); l1+=(1<

 

转载于:https://www.cnblogs.com/popo-black-cat/p/10686545.html

你可能感兴趣的文章
Python(软件目录结构规范)
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
条件断点 符号断点
查看>>
.net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串------(转)...
查看>>
python的多行注释
查看>>
连接Oracle需要jar包和javadoc文档的下载
查看>>
Dreamweaver cc新版本css单行显示
查看>>
【android】安卓的权限提示及版本相关
查看>>
Java基础教程——网络基础知识
查看>>
Kruskal基础最小生成树
查看>>
【hdu 1429】胜利大逃亡(续)
查看>>
关于收费软件
查看>>
javascript之Style物
查看>>
图的深度优先遍历
查看>>
C# 之 提高WebService性能大数据量网络传输处理
查看>>
Factory Design Pattern
查看>>
P1192-台阶问题
查看>>
一、使用pip安装Python包
查看>>
Duilib扩展《01》— 双击、右键消息扩展
查看>>