[Luogu P3295][SCOI 2016]萌萌哒
先说下暴力做法,如果[l1,r1]和[l2,r2]子串相等等价于两个区间内每个数对应相等。那么可以用并查集暴力维护,把对应相等的数的位置维护到同一个集合里去,最后答案其实就是把每个集合可以放的数个数乘起来就行了。注意:最高位不为0,如果有num个集合,则答案为9 * 10^(num – 1)。
暴力维护复杂度为nm,每次询问枚举每个区间内的点,即n个点;查询集合个数复杂度为n,故总时间复杂度为nm + n ≈O(n²)
实际评测30分。
#include<cstdio>
#include<cmath>
#define N 100010
#define ll long
const ll mod = ;
using namespace std;
ll fa[N],n,m,l1,r1,l2,r2;
ll qpow(ll a,ll b)//快速幂
{
ll ret = ;
while(b)
{
if(b & ) ret = ret * a % mod;
a = a * a % mod;
b >>= ;
}
return ret;
}
void reset_fa()
{
for(ll i = ;i <= n;i++) fa[i] = i;
return;
}
ll find(ll x)
{
if(fa[x] == x) return fa[x];
else return fa[x] = find(fa[x]);
}
int main()
{
scanf("%lld %lld",&n,&m);
reset_fa();
for(ll i = ;i <= m;i++)
{
scanf("%lld %lld %lld %lld",&l1,&r1,&l2,&r2);
for(ll j = ;j <= r1 - l1;j++) fa[find(l1 + j)] = find(l2 + j);//并查集暴力维护
}
ll num = ;
for(ll i = ;i <= n;i++)
if(fa[i] == i) num++;//查找集合个数
printf("%lld", * qpow(,num - ) % mod);
return ;
}
暴力代码
然后考虑优化,看数据范围,显然应该从nm部分下手,原本是一个一个点暴力维护,我们可以考虑对区间二进制拆分,拆成多个区间进行合并,复杂度就可以降到nlogn。或者从ST表角度理解也行,本质相同
#include<cstdio>
#include<cmath>
#define N 100010
#define ll long long
const ll mod = ;
using namespace std;
ll fa[N][];
ll n,m,l1,r1,l2,r2;
ll qpow(ll a,ll b)
{
ll ret = ;
while(b)
{
if(b & ) ret = ret * a % mod;
a = a * a % mod;
b >>= ;
}
return ret;
}
void reset_fa()
{
for(ll i = ;i <= n;i++)
for(ll j = ;j <= ;j++)
fa[i][j] = i;
return;
}
ll find(ll x,ll y)
{
if(fa[x][y] == x) return fa[x][y];
else return fa[x][y] = find(fa[x][y],y);
}
void merge(ll x,ll y,ll j)
{
if(find(x,j) != find(y,j))
{
fa[fa[x][j]][j] = fa[y][j];//区间[x,x + 2^j]和[y,y + 2^j]的合并
}
return;
}
int main()
{
scanf("%lld %lld",&n,&m);
reset_fa();
for(ll i = ;i <= m;i++)
{
scanf("%lld %lld %lld %lld",&l1,&r1,&l2,&r2);
for(ll j = ;j >= ;j--)
{
if(l1 + (( << j) - ) <= r1)
{
merge(l1,l2,j);
l1 += ( << j);//二进制拆分
l2 += ( << j);
}
}
}
for(ll j = ;j > ;j--)
{
for(ll i = ;i + ( << j) - <= n;i++)
{
merge(i,find(i,j),j - );
merge(i + ( << (j - )),fa[i][j] + ( << (j - )),j - );//把拆分的区间再合并回来。
}
}
ll num = ;
for(ll i = ;i <= n;i++)
{
if(find(i,) == i) num++;//查找区间个数
}
printf("%lld", * qpow(,num - ) % mod);
return ;
}
倍增AC代码
[Luogu P3295][SCOI 2016]萌萌哒的更多相关文章
- SCOI 2016 萌萌哒
SCOI 2016 萌萌哒 solution 有点线段树的味道,但是并不是用线段树来做,而是用到另外一个区间修改和查询的利器--ST表 我们可以将一个点拆成\(logN\)个点,分别代表从点\(i\) ...
- Luogu P3295 [SCOI2016]萌萌哒(并查集+倍增)
P3295 [SCOI2016]萌萌哒 题面 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位, ...
- 【BZOJ 4569】【SCOI 2016】萌萌哒
http://www.lydsy.com/JudgeOnline/problem.php?id=4569 用ST表表示所有区间,根据ST表中表示的区间长度种一棵nlogn的树,类似线段树,每个节点的左 ...
- luogu P3295 [SCOI2016]萌萌哒
传送门 题目条件"两个子串\(S[l_1,r_1],S[l_2,r_2]\)完全相同"等价于\(\forall i \in[0,r_1-l_1+1],S_{l1+i}=S_{l_2 ...
- 【BZOJ 4568】【SCOI 2016】幸运数字
写了一天啊,调了好久,对拍了无数次都拍不出错来(数据生成器太弱了没办法啊). 错误1:把线性基存成结构体,并作为函数计算,最后赋值给调用函数的变量时无疑加大了计算量导致TLE 错误2:像这种函数(A, ...
- [SCOI 2016]美味
Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) . \(m\) 组询问 \((b,x,l,r)\) 询问 \[\max_{i=l}^r b\oplus (A_i+x) ...
- [SCOI 2016]幸运数字
Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一 ...
- [SCOI 2016]背单词
Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计 ...
- bzoj 4568 [SCOI 2016] 幸运数字
题目大意 给定一棵\(n\)个点的树,每个点有权值 \(q\)次询问树上路径中 每个点权值可选可不选的最大异或和 \(n\le 2*10^4,q\le 2*10^5,val[i]\le 2^{60}\ ...
随机推荐
- VMware14虚拟机下安装Centos6.5
一.下载VMware14,CentOS6.5光盘映像文件. https://pan.baidu.com/s/1WaTBnYuNC5dLYM_Ra2bjBQ 二.安装过程 1.打开VMware虚拟机 — ...
- 解决Base64报错
- 详解vuex结合localstorage动态监听storage的变化
这篇文章主要介绍了详解vuex结合localstorage动态监听storage的变化,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 需求:不同组件间共用同一数据,当一个 ...
- JDK内置工具使用(jps、jstack、jmap、jstat)
一.JPS 1.jps -lvm:用于查看当前机器上已装载的jvm 二.jstackjstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁) 1.jstack -l pid ...
- dede 5.7 任意用户重置密码前台
返回了重置的链接,还要把&删除了,就可以重置密码了 结果只能改test的密码,进去过后,这个居然是admin的密码,有点头大,感觉这样就没有意思了 我是直接上传的一句话,用菜刀连才有乐趣 ...
- 将List按照指定大小等分的几种实现方式和效率对比及优化
今天碰到一个需求,定时任务,批量从表里取数据并做一些其他操作然后再存表,每次取1000条,由于计算过程比较耗时所以要起多个线程同时跑,需要将List按照指定大小等分,如每100条数据起一个线程,若最后 ...
- BZOJ3709 Bohater 贪心
传送门 思路很妙-- 有个前提条件:血量无限,这样话肯定先打会回血的怪,再打会掉血的怪 对于会回血的怪,按照受到伤害的顺序从小往大打 对于会掉血的怪似乎并不是很好搞,考虑:将每一时刻的血量函数画出来, ...
- Java 开发笔记2
Java获取参数名称 https://blog.csdn.net/z69183787/article/details/81117525 DefaultParameterNameDiscoverer() ...
- Filter过滤要登录的页面(重要)
一.为什么要写过滤器,过滤页面? 本人做了一个网站,目前还在开发.做过滤器的目的就是为了要过滤一些页面必需要用户登录之后才能看,主页什么的可以随便看,一旦涉及到要发布或评论什么信息,就必须要过滤用户的 ...
- Linux 学习 (三) 文件搜索命令
Linux达人养成计划 I 学习笔记 locate 文件名 搜索速度比较快 只能根据文件名搜索 搜索的是保存在 /var/lib/mlocate 的数据库(每天更新一次) 新建文件需要执行 updat ...