洛谷P3295 萌萌哒 并查集 + ST表
又切一道紫题!!!
成功的(看了一吨题解之后),我A掉了第二道紫题。
好,我们仔细观察,发现这是一个排列组合问题。
有些限定条件,要相等的地方,我们就用并查集并起来。最后一查有多少个并查集,就有多少个位置可供自由选择。
所以答案就是10^(并查集数),去除前导0:*(9/10)
好,这样我们得到了一个O(mn)算法。
然后我们考虑优化:每个区间可能被合并多次。所以我们有两种选择:线段树/ST表。
考虑到这是ST表例题(???????),我们就来个ST表与并查集联动求解...
我们的ufs[i][j]代表在[i][2^j]这个区间内的情况。
然后每次合并的时候都往下合并两个j-1(也可以最后再一起下传标记)
实质上是开了logn个并查集,因为我发现find和merge都不跨层。
题外话:与RE战斗的艰辛历程
交了11次RE,实在是让人感受绝望啊。
两种方法全都RE,所幸刚才我写的时候都查出来错了。
那么先来看看第一种方法:
每次都跟线段树一样恰好标记完最少的节点,最后所有标记一起下传。
#include <cstdio>
using namespace std;
const int N = ;
const int mo = ; int ufs[N][],n,m;
int find(int x,int j)
{
if(ufs[x][j]!=x) ufs[x][j]=find(ufs[x][j],j);
return ufs[x][j];
}
void merge(int x,int y,int j)
{
ufs[find(x,j)][j]=find(y,j);///->!!这里调了一个错,之前是ufs[x][j]=......
return;
} int main()
{
scanf("%d%d",&n,&m);
for(int j=;j<=;j++)
{
for(int i=;i<=n;i++) ufs[i][j]=i;///->!
}
int a,b,c,d;
int md=;
while((<<md)<=n) md++;
md--;
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int j=md;j>=;j--)
{
if(a+(<<j)-<=b) merge(a,c,j),a+=(<<j),c+=(<<j);
}
}
///
for(int j=md;j>=;j--)///这里,RE的罪魁祸首!我之前写的0,结果传进去个j=-1直接挂
{
for(int i=;i+(<<j)-<=n;i++)
{
merge(i,find(i,j),j-);
merge(i+(<<(j-)),find(i,j)+(<<(j-)),j-);
}
}
///
long long ans=;
bool q=false;
for(int i=;i<=n;i++)
{
if(find(i,)==i)
{
if(q) ans=(ans*)%mo;
q=;
}
}
//for(int i=1;i<=n;i++) printf("%d ",find(i,0));
printf("%lld",ans);
return ;
}
AC代码,跑的比下面快一些
第二种思路:
每次都传到底。如果已经在一起就不往下推了。
#include <cstdio>
using namespace std;
const int N = ;
const int mo = ; int ufs[N][],n,m;
int ffind(int x,int j)
{
//if(ufs[x][j]!=x) ufs[x][j]=find(ufs[x][j],j);
//return ufs[x][j];
if(j<) return ;
int ans=x,k;
while(ufs[ans][j]!=ans) ans=ufs[ans][j];
while(ufs[x][j]!=x)
{
k=ufs[x][j];
ufs[x][j]=ans;
x=k;
}
return ans;
}
void mmerge(int x,int y,int j)
{
if(j<) return;///这里控制情况,AC
if(ffind(x,j)==ffind(y,j)) return;
ufs[ffind(x,j)][j]=ffind(y,j);///->!!
mmerge(x,y,j-),mmerge(x+(<<(j-)),y+(<<(j-)),j-);///这里RE!会传入j=-1
return;
} int main()
{
scanf("%d%d",&n,&m);
for(int j=;j<=;j++)
{
for(int i=;i<=n;i++) ufs[i][j]=i;///->!
}
int a,b,c,d;
int md=;
while((<<md)<=n) md++;
md--;
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int j=md;j>=;j--)
{
if(a+(<<j)-<=b) mmerge(a,c,j),a+=(<<j),c+=(<<j);
}
}
/** */
long long ans=;
bool q=false;
for(int i=;i<=n;i++)
{
if(ffind(i,)==i)
{
if(q) ans=(ans*)%mo;
q=;
}
}
//for(int i=1;i<=n;i++) printf("%d ",find(i,0));
printf("%lld",ans);
return ;
}
AC代码
结论:函数里最好写上特判违法情况,保险。
洛谷P3295 萌萌哒 并查集 + ST表的更多相关文章
- bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表
题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每 ...
- luogu3295 萌萌哒 (并查集+ST表)
如果给相同的位置连边,最后联通块数是n,最后答案就是$9*10^{n-1}$ 但直接连边是$O(n^2)$的 所以事先处理出一个ST表,每次O(1)地给那个ST表连边 最后再一点一点下放,就是把在这层 ...
- 【洛谷3865】 【模板】ST表(猫树)
传送门 洛谷 Solution 实测跑的比ST表快!!! 这个东西也是\(O(1)\)的,不会可以看我上一篇Blog 代码实现 代码戳这里
- 洛谷P3295 萌萌哒 [SCOI2016] 倍增+并查集
正解:倍增+并查集 解题报告: 传送门! 首先不难想到暴力?就考虑把区间相等转化成对应点对相等,然后直接对应点连边,最后求有几个连通块就好辣 然后看下复杂度,修改是O(n2)查询是O(n),就比较容易 ...
- 洛谷P4092树——并查集
题目:https://www.luogu.org/problemnew/show/P4092 利用并查集,倒序离线,那么从倒序来看被撤销标记的点就再也不会被标记,所以用并查集跳过: 莫名其妙的WA,调 ...
- 洛谷P2391 白雪皑皑(并查集)
题目背景 “柴门闻犬吠,风雪夜归人”,冬天,不期而至.千里冰封,万里雪飘.空中刮起了鸭毛大雪.雪花纷纷,降落人间. 美能量星球(pty 在 spore 上的一个殖民地)上的人们被这美景所震撼.但是 p ...
- 洛谷P3958 奶酪 并查集
两个空洞可互达当且仅当两个空洞相切,即球心距离小于等于球的直径. 一一枚举两个可互达的空洞,并用并查集连起来即可. Code: #include<cstdio> #include<c ...
- 洛谷 P3958 奶酪 并查集
目录 题面 题目链接 题面 题目描述 输入输出格式 输入格式 输出格式: 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P3958 奶酪 题面 题目描述 现有一块大奶酪 ...
- 洛谷 P2391.白雪皑皑 (并查集,思维)
题意:有\(n\)个点,对这些点进行\(m\)次染色,第\(i\)次染色会把区间\((i*p+q)\ mod\ N+1\)和\((i*q+p)\ mod\ N+1\)之间的点染成颜色\(i\),问最后 ...
随机推荐
- 2018年高教社杯全国大学生数学建模竞赛C题解题思路
题目 C题 大型百货商场会员画像描绘 在零售行业中,会员价值体现在持续不断地为零售运营商带来稳定的销售额和利润,同时也为零售运营商策略的制定提供数据支持.零售行业会采取各种不同方法来吸引更多的人成 ...
- Jvm 10 升级笔记
移除了 JPEGCodec https://www.cnblogs.com/liaolongjun/p/6878359.html
- Beta版会议总结
开会时间:2015年06月12日 开会地点:基教601 开会人员:李想,王颖瑞,朱少辉,陈晨,侯涛亮. 开会内容:对于6月10日,大一同学的投票情况进行讨论和反思. 讨论结果如下: 一.目前存在的问题 ...
- svn 使用教程
一.什么是SVN SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. 二.SVN的下载安装 下载地址:http ...
- 8-Python3从入门到实战—基础之数据类型(集合-Sets)
Python从入门到实战系列--目录 集合的定义 集合(set)和字典类似,也是一组key的集合,但不存储value:由于key不能重复,所以,在set中,没有重复的key. 创建一个set,需要提供 ...
- mysql 备份数据库 mysqldump
@echo off for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE ...
- 变更RHEL(Red Hat Enterprise Linux 5.8)更新源使之自动更新
HP 4411s Install Red Hat Enterprise Linux 5.8) pick up from http://blog.chinaunix.net/uid-423637-id- ...
- vuex的数据交互
methods:{ ...mapMutations({aaa:hs}) //将mutations的方法暴露出来,进行调用 aaa是他的名字 ...mapActions(['hs']) //将actio ...
- NodeJS 学习记录
这里是我学习NodeJs的学习记录 URL:网址解析的好帮手 URL,URI 首先,URI是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源.而URL是u ...
- as_matrix、保存训练模型
#-*- coding: utf-8 -*- #构建并测试CART决策树模型 import pandas as pd #导入数据分析库 from random import shuffle #导入随机 ...