link

Description

一个长度为 $ n $ 的大数,用 $ S_1S_2S_3 \ldots S_n $表示,其中 $ S_i $ 表示数的第 $ i $ 位,$ S_1 $ 是数的最高位,告诉你一些限制条件,每个条件表示为四个数 $ (l_1, r_1, l_2, r_2) $,即两个长度相同的区间,表示子串 $ S_{l_1}S_{l_1 + 1}S_{l_1 + 2} \ldots S_{r_1} $ 与 $ S_{l_2}S_{l_2 + 1}S_{l_2 + 2} \ldots S_{r_2} $ 完全相同。

比如 $ n = 6 $ 时,某限制条件 $ (l_1 = 1, r_1 = 3, l_2 = 4, r_2 = 6) $,那么 $ 123123 \(、\) 351351 $ 均满足条件,但是 $ 12012 \(、\) 131141 $ 不满足条件,前者数的长度不为 $ 6 $,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

\(n\le 10^5\)

Solution

可以想到,我们用 \(f_{i,j}\) 表示 \([i,i+2^j-1]\) 这一段区间,然后每次合并两个区间就相当于合并 \(f_{l1,k},f_{l2,k}\) 以及 \(f_{r1-2^k+1,k},f_{r2-2^k+1,k}\) 。

然后我们还需要将儿子也下传一下合并标记即可。

Code

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define mod 1000000007
#define MAXN 100005 template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);} int n,m,tot,lg[MAXN],f[MAXN][21],ls[MAXN * 21],rs[MAXN * 21],fa[MAXN * 21]; int findSet (int x){return fa[x] == x ? x : fa[x] = findSet (fa[x]);}
void unionSet (int x,int y){
x = findSet (x),y = findSet (y);
if (x == y) return ;
fa[y] = x;
} signed main(){
read (n,m);
for (Int i = 2;i <= n;++ i) lg[i] = lg[i >> 1] + 1;
for (Int j = 0;(1 << j) <= n;++ j)
for (Int i = 1;i + (1 << j) - 1 <= n;++ i)
f[i][j] = ++ tot,fa[tot] = tot;
for (Int j = 1;(1 << j) <= n;++ j)
for (Int i = 1;i + (1 << j) - 1 <= n;++ i)
ls[f[i][j]] = f[i][j - 1],rs[f[i][j]] = f[i + (1 << j - 1)][j - 1];
for (Int i = 1;i <= m;++ i){
int l1,r1,l2,r2;read (l1,r1,l2,r2);
int k = lg[r1 - l1 + 1];
unionSet (f[l1][k],f[l2][k]);
unionSet (f[r1 - (1 << k) + 1][k],f[r2 - (1 << k) + 1][k]);
}
for (Int j = lg[n];j >= 1;-- j)
for (Int i = 1;i + (1 << j) - 1 <= n;++ i){
int t = findSet (f[i][j]);
if (t == f[i][j]) continue;
unionSet (ls[t],ls[f[i][j]]);
unionSet (rs[t],rs[f[i][j]]);
}
int cnt = n,res = 9;
for (Int i = 1;i <= n;++ i) if (findSet (f[i][0]) != f[i][0]) cnt --;
for (Int i = 1;i < cnt;++ i) res = 1ll * res * 10 % mod;
write (res),putchar ('\n');
return 0;
}

题解 「SCOI2016」萌萌哒的更多相关文章

  1. 「SCOI2016」萌萌哒 解题报告

    「SCOI2016」萌萌哒 这思路厉害啊.. 容易发现有个暴力是并查集 然后我想了半天线段树优化无果 然后正解是倍增优化并查集 有这个思路就简单了,就是开一个并查集代表每个开头\(i\)每个长\(2^ ...

  2. 「SCOI2016」萌萌哒

    「SCOI2016」萌萌哒 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \ldots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位,\(S_1\) 是数 ...

  3. 【LOJ】#2014. 「SCOI2016」萌萌哒

    题解 这个题好妙啊 首先我们发现,如果我们可以暴力,就是把相同的元素拿并查集合起来,最后统计集合个数\(cnt\) 答案是\(9\*10^{cnt - 1}\) 然而我们做不到= = 我们可以用倍增的 ...

  4. LOJ#2014「SCOI2016」萌萌哒(倍增,并查集优化连边)

    题面 点此看题 题意很明白,就不转述了吧. 题解 题目相当于告诉了我们若干等量关系,每个限制 l 1 , r 1 , l 2 , r 2 \tt l_1,r_1,l_2,r_2 l1​,r1​,l2​ ...

  5. loj2014 「SCOI2016」萌萌哒

    神tm st表+并查集 #include <iostream> #include <cstdio> #include <cmath> using namespace ...

  6. loj#2013. 「SCOI2016」幸运数字 点分治/线性基

    题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...

  7. loj#2015. 「SCOI2016」妖怪 凸函数/三分

    题目链接 loj#2015. 「SCOI2016」妖怪 题解 对于每一项展开 的到\(atk+\frac{dnf}{b}a + dnf + \frac{atk}{a} b\) 令$T = \frac{ ...

  8. loj#2016. 「SCOI2016」美味

    题目链接 loj#2016. 「SCOI2016」美味 题解 对于不带x的怎么做....可持久化trie树 对于带x,和trie树一样贪心 对于答案的二进制位,从高往低位贪心, 二进制可以表示所有的数 ...

  9. loj#2012. 「SCOI2016」背单词

    题目链接 loj#2012. 「SCOI2016」背单词 题解 题面描述有点不清楚. 考虑贪心 type1的花费一定不会是优的,不考虑, 所以先把后缀填进去,对于反串建trie树, 先填父亲再填儿子, ...

随机推荐

  1. ES6扩展——箭头函数

    1.箭头函数 在es6中,单一参数的单行箭头函数语法结构可以总结如下: const 函数名 = 传入的参数 => 函数返回的内容,因此针对于 const pop = arr => arr. ...

  2. springboot系列总结(二)---springboot的常用注解

    上一篇文章我们简单讲了一下@SpringBootApplication这个注解,申明让spring boot自动给程序进行必要的配置,他是一个组合注解,包含了@ComponentScan.@Confi ...

  3. 24点游戏(24 game)的C++编程求解实现

    什么是24点游戏 24点游戏,英文叫做24 game,是对给定的4个非负整数进行加减乘除运算,要求每个数都要被用到且仅用到一次,并得到最终的运算结果为24.比如3.8.3.8这四个数,可以找出唯一的一 ...

  4. 二、grep文本搜索工具

    grep命令作为Unix中用于文本搜索的神奇工具,能够接受正则表达式,生成各种格式的输出.除此外,它还有大量有趣的选项. # 搜索包含特定模式的文本行: [root@centos8 ~]#grep p ...

  5. 代码注释规范之Doxygen

    1.Doxygen简介 Doxygen是一个程序的文档产生工具,可以将程序中的注释转换成说明文档或者说是API参考手册,从而减少程序员整理文档的时间.当然这里程序中的注释需要遵循一定的规则书写,才能让 ...

  6. ClientValidationFunction

    CustomValidator.ClientValidationFunction 属性 获取或设置用于验证的自定义客户端脚本函数的名称. 命名空间:   System.Web.UI.WebContro ...

  7. web、html概念快速入门

    1.C/S和B/S 总结,理论上如果硬件不考虑(带宽.(图像资源加载)显卡等),B/S可以完全替代C/S: 2.静态资源和动态资源 其中,访问时动态资源,服务器后台也会通过视图解析器转换成静态资源,因 ...

  8. [第八篇]——Docker 容器使用之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker 客户端 docker 客户端非常简单 ,我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项. xxx@xxx:~# docker 可以通过命令  docke ...

  9. composer 包 slim使用案例,一个简单的路由解决方案

    nginx配置文件修改 location / { try_files $uri /index.php$is_args$args; } 设置好nginx伪静态,把所有的请求方式都转向到index.php ...

  10. 使用git克隆仓库到本地报错:SSL certificate problem: unable to get local issuer certificate

    第一次使用Git工具克隆仓库,使用的是HTTPS链接,失败了.发现是因为通过HTTPS访问时,如果服务器上的SSL证书未经过第三方机构认证,Git就会报错. 解决方法:通过命令关闭验证 git con ...