[BZOJ4569][SCOI2016]萌萌哒(倍增+并查集)
首先有一个显然的$O(n^2)$暴力做法,将每个位置看成点,然后将所有限制相等的数之间用并查集合并,最后答案就是9*(10^连通块的个数)。(特判n=1时就是10)。
然后比较容易想到的是,由于每次合并的是一个区间,逐个合并点过于浪费时间,考虑用线段树建图优化复杂度,但发现线段树建图并不能支持题目中的操作。
考虑常用来替代线段树的ST表,对每个点i拆成log个,[j][i]表示i~i+(2^j)-1这段区间,我们称它为i在第j层的点。
对于每个限制,将它拆成log个长度为2的次幂的区间,并分别在层内连边。
所有限制处理完后,从第log(n)层(最高层)逐层下放信息。若[j][a]与[j][b]有边,那么将[j-1][a]与[j-1][b]连边,[j-1][a+(1<<(j-1))]与[j-1][b+(1<<(j-1))]连边。当然若两个同层点已经在同一个连通块中则可以不用连边。
这样我们成功将边数降到nlog级别,且第0层能完全记录所有限制信息,最后所求的答案就是9*(10^第0层的连通块个数)。
若不考虑并查集复杂度,每个限制被拆成log个,每层中每个点只会下放两条边,共log层,故总复杂度$O((m+n)\log n)$。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,mod=1e9+;
int n,m,sm,ans=,a,b,c,d,f[][N],lg[N]; int find(int k,int x){ return (f[k][x]==x) ? x : f[k][x]=find(k,f[k][x]); }
void uni(int k,int a,int b){ if (find(k,a)!=find(k,b)) f[k][f[k][a]]=f[k][b]; } int main(){
freopen("bzoj4569.in","r",stdin);
freopen("bzoj4569.out","w",stdout);
scanf("%d%d",&n,&m);
if (n==){ puts(""); return ; }
rep(i,,n) lg[i]=lg[i>>]+;
rep(j,,lg[n]) rep(i,,n-(<<j)+) f[j][i]=i;
rep(i,,m){
scanf("%d%d%d%d",&a,&b,&c,&d);
for (int j=lg[b-a+]; ~j; j--) if (a+(<<j)-<=b)
uni(j,a,c),a+=<<j,c+=<<j;
}
for (int j=lg[n]; j; j--) rep(i,,n-(<<j)+)
uni(j-,i,find(j,i)),uni(j-,i+(<<(j-)),f[j][i]+(<<(j-)));
rep(i,,n) if (find(,i)==i) sm++;
rep(i,,sm) ans=ans*10ll%mod;
printf("%d\n",ans);
return ;
}
[BZOJ4569][SCOI2016]萌萌哒(倍增+并查集)的更多相关文章
- 【BZOJ4569】[Scoi2016]萌萌哒 倍增+并查集
[BZOJ4569][Scoi2016]萌萌哒 Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四 ...
- BZOJ4569 [SCOI2016]萌萌哒 【并查集 + 倍增】
题目链接 BZOJ4569 题解 倍增的思想很棒 题目实际上就是每次让我们合并两个区间对应位置的数,最后的答案\(ans = 9 \times 10^{tot - 1}\),\(tot\)是联通块数, ...
- 2018.07.31 bzoj4569: [Scoi2016]萌萌哒(并查集+倍增)
传送门 对于每个限制,使用倍增的二进制拆分思想,用并查集数组fa[i][j]" role="presentation" style="position: rel ...
- [SCOI2016]萌萌哒(倍增+并查集)
一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1 ...
- BZOJ4569 [Scoi2016]萌萌哒(并查集,倍增)
类似\(ST表\)的思想,倍增\(log(n)\)地合并 你是我家的吗?不是就来呀啦啦啦.还有要来的吗?没了!那有多少个家就映射多少答案呀 倍增原来这么好玩 #include <iostream ...
- 【BZOJ4569】萌萌哒(并查集,倍增)
[BZOJ4569]萌萌哒(并查集,倍增) 题面 BZOJ 题意: 有一个长度为\(n\)的数 给定\(m\)个限制条件 每次限制\(l1-r1\)与\(l2-r2\)是相同的 求出方案数 题解 如果 ...
- 洛谷P3295 萌萌哒 [SCOI2016] 倍增+并查集
正解:倍增+并查集 解题报告: 传送门! 首先不难想到暴力?就考虑把区间相等转化成对应点对相等,然后直接对应点连边,最后求有几个连通块就好辣 然后看下复杂度,修改是O(n2)查询是O(n),就比较容易 ...
- BZOJ4569 SCOI2016萌萌哒(倍增+并查集)
一个显然的暴力是用并查集记录哪些位之间是相等的.但是这样需要连nm条边,而实际上至多只有n条边是有用的,冗余过多. 于是考虑优化.使用类似st表的东西,f[i][j]表示i~i+2^j-1与f[i][ ...
- 【BZOJ 4569】 4569: [Scoi2016]萌萌哒 (倍增+并查集)
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 865 Solved: 414 Description 一个长 ...
随机推荐
- 解决Maven并行编译中出现打包错误问题的思路
解决Maven并行编译中出现打包错误问题的思路 并行构建 Maven 3.x 提供了并行编译的能力,通过执行下列命令就可以利用构建服务器的多线程/多核性能提升构建速度: mvn -T 4 clean ...
- iOS学习笔记(2)— UIView用户事件响应
UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为 ...
- 结构体变量的sizeof计算
结构体字节对齐准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除: 2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节: ...
- 多校 HDU 6397 Character Encoding (容斥)
题意:在0~n-1个数里选m个数和为k,数字可以重复选: 如果是在m个xi>0的情况下就相当于是将k个球分割成m块,那么很明显就是隔板法插空,不能为0的条件限制下一共k-1个位置可以选择插入隔板 ...
- Jenkins远程调度Shell命令
http://blog.csdn.net/fireofjava/article/details/40624353 Jenkins服务器为Win7版本,需要远程调用CentOS服务器上Shell脚本,然 ...
- Flask:初次使用Flask-SQLAlchemy读取SQLite3
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2,Eclipse Oxygen.1a Release (4.7.1a),PyDev 6.3.2 SQLAlchemy是一 ...
- Hash 分布均衡算法
1.移位实现 public static int GetIndex(string str, int count) { , (current, c) => (current << ) ...
- xgboost gbdt特征点分烈点
lightGBM与XGBoost的区别:(来源于:http://baijiahao.baidu.com/s?id=1588002707760744935&wfr=spider&for= ...
- day05作业
一.1.switch 2.字符串 3.表达式1 4.break 5.continue 二.1.B 2.A 3.BD 4.D 5.B 6.B 7.A 8.D 9.D 10.B 三.1.√ 2.√ 3.× ...
- pip3
pip3 install django #安装rabbitmq连接模块 pip3 install pika pip3 install paramiko pip3 install ipython pip ...