[BZOJ 4569][SCOI 2016] 萌萌哒 区间并查集(ST表思想)
来源:互联网 发布:产品图册制作软件 编辑:程序博客网 时间:2024/05/16 11:18
题目传送门:【BZOJ 4569】
题目大意: 有一个长度为 n 的大数。告诉你一些限制条件,每个条件表示为四个数,L1,R1,L2,R2,即两个长度相同的区间,表示区间内对应的数相同。比如 n=6 时,某限制条件 L1=1,R1=3,L2=4,R2=6,那么 123123,351351 这两组数均满足条件,但是 12012,131141 这两组数不满足条件,前者数的长度不为 6,后者第二位与第五位不同。现在,请你求出,满足以上所有条件的数有多少个。
题目分析:
在分析之前,先 Orz gengchen的题解 给我带来的启发
(这道题他讲得更详细,代码也更好懂)
进入正题
由题,首先看到这道题,由于题目性质为“对应的数位相等”,并且当数位之间有重合的时候,就会有对应的每个数都相等的情况(其实这样说是不准确的,但是,这些数至少都是相同的几组数),所以我们可以考虑使用并查集做法。
但是,朴素的并查集在这里会造成极大的浪费,很多情况被重复计算。所以,我们需要更好地优化并查集。在这里,我们可以使用最优的 ST 表优化方式(即:利用倍增的思想,对每个区块的数进行优化)。
具体的操作,可以看下面的代码,或者去上面看更详细的题解:
- #include<cstdio>
- #include<algorithm>
- typedef long long LL;
- const int MX=100005;
- const int MXLOG=20;
- const int MOD=998244353;
- int n,m,tot=0,ans=1;
- int f[MXLOG][MX],log[MX*MXLOG],fa[MX*MXLOG],left[MX*MXLOG],right[MX*MXLOG];
- //为了使用倍增而多开了log(n)的空间
- LL fastpow(int a,int b,int mod){
- LL r=1,base=a;
- while (b){
- if (b&1) r=r*base%mod;
- base=base*base%mod;
- b>>=1;
- }
- return r%mod;
- }
- void preprocess(int n){
- for (int i=1,j=0;i<=n;i<<=1,j++)log[i]=j;
- for (int i=1;i<=n;i++)log[i]=std::max(log[i-1],log[i]);
- for (int i=0;i<=log[n];i++){
- for (int j=1;j+(1<<i)-1<=n;j++){
- f[i][j]=++tot;
- if (i>0){
- //运用了ST表中的倍增思想
- left[tot]=f[i-1][j];
- right[tot]=f[i-1][j+(1<<(i-1))];
- }
- }
- }
- }
- inline int find(int x){
- if (fa[x]==x) return x;
- return fa[x]=find(fa[x]);
- }
- void merge(int lf,int rt){
- int x=find(lf),y=find(rt);
- if (x!=y) fa[x]=y;
- }
- int main(){
- int Li,Ri,li,ri;
- scanf(”%d%d”,&n,&m);
- if (n==1){
- printf(”10”);
- return 0;
- }
- preprocess(n);
- for (int i=1;i<=tot;i++) fa[i]=i;
- for (int i=1;i<=m;i++){
- scanf(”%d%d%d%d”,&Li,&Ri,&li,&ri);
- if (Li==li) continue;
- int size=log[Ri-Li+1];
- merge(f[size][Li],f[size][li]);
- merge(f[size][Ri-(1<<size)+1],f[size][ri-(1<<size)+1]);
- }
- for (int i=tot;i>n;i–){
- int j=find(i);
- if (i!=j){
- //对应位置合并
- merge(left[i],left[j]);
- merge(right[i],right[j]);
- }
- }
- for (int i=1;i<=n;i++)
- if (find(i)==i) ans=10LL*ans%MOD;
- printf(”%lld”,9LL*ans%MOD*fastpow(10,MOD-2,MOD)%MOD);
- return 0;
- }
阅读全文
1 0
- [BZOJ 4569][SCOI 2016] 萌萌哒 区间并查集(ST表思想)
- 【BZOJ 4569】【SCOI】【萌萌哒】【并查集】【倍增均摊优化】
- bzoj 4569: [Scoi2016]萌萌哒 (st表+并查集)
- bzoj 4569: [Scoi2016]萌萌哒 ST表+并查集
- BZOJ 4569: [Scoi2016]萌萌哒 ST表 并查集
- BZOJ 1854|SCOI 2010|游戏|并查集
- 【BZOJ 4569】【SCOI 2016】萌萌哒
- 【BZOJ4569】萌萌哒,ST表+并查集
- 【BZOJ 1854】【SCOI 2010】游戏【并查集 & 二分图匹配】
- 【bzoj4569】【SCOI2016】【萌萌哒】【st表+并查集】
- BZOJ4633 SCOI2016 萌萌哒 并查集维护ST表
- [BZOJ4569][Scoi2016]萌萌哒(并查集+st表)
- 【BZOJ4569】[Scoi2016]萌萌哒(并查集+st表)
- bzoj4569 [Scoi2016]萌萌哒 (st表 维护 并查集)
- 【bzoj 4569】[Scoi2016]萌萌哒 (并查集)
- BZOJ 4569 萌萌哒 (并查集)
- 【BZOJ 1068】【SCOI 2007】压缩 【区间DP】
- BZOJ 4569: [Scoi2016]萌萌哒【倍增并查集
- 协程的概念及Python中利用第三方库gevent使用协程
- MacBookPro2017下卸载Java9
- python爬虫随笔3 妹子图爬虫
- bzoj 2662: [BeiJing wc2012]冻结
- 第四周项目2——建设“单链表”算法库
- [BZOJ 4569][SCOI 2016] 萌萌哒 区间并查集(ST表思想)
- 包装类
- Android之litepal创建数据库失败
- 在Kali Linux中安装的拼音输入法
- linux 挂载时 mount: wrong fs type, bad option, bad superblock on /dev/sdb
- MATLAB2017安装教程
- APOI 2010 巡逻 直径
- 解决xcode9真机调试问题
- Android sdk的目录结构