[AGC003F] Fraction of Fractal(矩阵乘法)
Description
Snuke从他的母亲那里得到了生日礼物——一个网格。网格有H行W列。每个单元格都是黑色或白色。所有黑色单元格都是四联通的,也就是说,只做水平或垂直移动且只经过黑色单元格即可从任何黑色单元格移动到任何其他黑色单元格。
第i行第j列的单元格的颜色由字符si,j表示。如果si,j是 #,该单元格为黑色;如果si,j是 .,该单元格为白色。至少一个单元格是黑色的。
我们定义「分形」如下:0级分形是一个 1×1的黑色单元格.k级分形由H行W列较小一级的分形按照 Snuke 的网格的样式拼成:与Snuke 网格中的黑色单元格对应的位置是一个k级分形;与Snuke 网格中的白色单元格对应的位置是一个单元格全部为白色,尺寸与k级分形相同的网格。
您将得到 Snuke 的网格的描述和整数 K。请求出K级分形中黑色单元格组成的连通分量数,模1000000007。
Input
第一行三个整数H,W,K如题目描述
接下来H行,每行W个字符
Output
输出K级分形中黑色单元格组成的连通分量数,模1000000007。
题解:
一看 \(K=10^8\) 肯定是log级别的算法,一下想到矩阵快速幂。
首先,一个网格的上面和下面,左边和右边都连通,那么不管怎么分它都是连通的,所以答案是 \(1\)。
如果一个网格上面和下面,左边和右边都不连通,那么不管怎么分都是不连通的,所以答案是 \(x^{k-1}\),\(x\) 为黑块总个数。
剩下就是行连通,列不连通了。(不然转一下就好了)
x[k] 表示 k 级分型有多少个黑块。
y[k] 表示 k 级分型有多少个黑块满足这行的下一个也是黑块。
z[k] 表示 k 级分型有多少行是连通的。
手推可得:
\(x[k]=x[k-1]^2\)
\(y[k]=x[k-1]y[k-1]+z[k-1]y[k-1]\)
\(z[k]=z[k-1]^2\)
构造矩阵:
x & y \\
0 & z
\end{matrix}\right ] \]
求这个矩阵的 \(k-1\) 次方,答案为 \(x-y\)。
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mod 1000000007
int n,m;
char s[1005][1005],tmp[1005][1005];
long long k;
struct Matrix{
long long mat[5][5];
Matrix(){memset(mat,0,sizeof(mat));}
Matrix operator*(const Matrix &b)const{
Matrix c;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++){
for(int k=1;k<=2;k++)
c.mat[i][j]+=mat[i][k]*b.mat[k][j];
c.mat[i][j]%=mod;
}
return c;
}
Matrix operator^(long long x)const{
Matrix a(*this),ans;
for(int i=1;i<=2;i++)ans.mat[i][i]=1;
while(x){
if(x&1)ans=ans*a;
x>>=1,a=a*a;
}
return ans;
}
}mat;
int qpow(int x,long long y){
int ans=1;
while(y){
if(y&1)ans=1LL*ans*x%mod;
y>>=1,x=1LL*x*x%mod;
}
return ans;
}
bool check(){
for(int i=1;i<=n;i++)
if(s[i][1]=='#'&&s[i][m]=='#')return true;
return false;
}
void turn(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
tmp[m-j+1][i]=s[i][j];
swap(n,m);
memcpy(s,tmp,sizeof(s));
}
int main(){
scanf("%d%d%lld",&n,&m,&k);
int x=0,y=0,z=0;
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++)x+=s[i][j]=='#';
}
bool a=check(),b=(turn(),check());turn();
if(a&&b)return printf("1"),0;
else if(!a&&!b)return printf("%d",qpow(x,k-1)),0;
else if(b)turn();
for(int i=1;i<=n;i++)
z+=s[i][1]=='#'&&s[i][m]=='#';
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)y+=s[i][j]=='#'&&s[i][j+1]=='#';
mat.mat[1][1]=x,mat.mat[1][2]=y,mat.mat[2][2]=z;
mat=mat^(k-1);
printf("%lld",(mat.mat[1][1]-mat.mat[1][2]+mod)%mod);
}
[AGC003F] Fraction of Fractal(矩阵乘法)的更多相关文章
- [AGC003F] Fraction of Fractal 矩阵快速幂
Description SnukeSnuke从他的母亲那里得到了生日礼物--一个网格.网格有HH行WW列.每个单元格都是黑色或白色.所有黑色单元格都是四联通的,也就是说,只做水平或垂直移动且只经过 ...
- @atcoder - AGC003F@ Fraction of Fractal
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 H*W 黑白格图,保证黑格四连通. 定义分形如下:0 ...
- [agc003F]Fraction of Fractal
Description 传送门 Solution 本篇博客思路来自大佬的博客(侵删). 我们定义如果网格的第一行和最后一行的第i列都为黑色,则它是一个上下界接口.左右界接口定义同上. 如果上下界接口和 ...
- *HDU2254 矩阵乘法
奥运 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- *HDU 1757 矩阵乘法
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- CH Round #30 摆花[矩阵乘法]
摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...
- POJ3070 Fibonacci[矩阵乘法]
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13677 Accepted: 9697 Descri ...
- bzoj 2738 矩阵乘法
其实这题跟矩阵乘法没有任何卵关系,直接整体二分,用二维树状数组维护(刚刚学会>_<),复杂度好像有点爆炸(好像有十几亿不知道是不是算错了),但我们不能怂啊23333. #include&l ...
- 【BZOJ-2476】战场的数目 矩阵乘法 + 递推
2476: 战场的数目 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 58 Solved: 38[Submit][Status][Discuss] D ...
随机推荐
- Eclipse 发布 JAR
明确要生成何种类型 jar 生成工具 jar,作为包被其他程序调用 具体步骤: 选中项目文件,点右键选择 Export ,JAR File 在弹出窗口选择,导出哪些文件,并且选择好 输出 JAR 的路 ...
- 关于mybatis callSettersOnNulls 配置
今天做了一件坑了自己的事情,为此浪费了好多时间... 在mybatis的设置中,看到了这样的一行设置.出于程序员的好奇,去搜索了一下,这条设置是干什么的. <setting name=" ...
- DevOps - 监控告警 - Zabbix
官网3.4版本中文文档 Zabbix documentation in Chinese [Zabbix Documentation 3.4] https://www.zabbix.com/docume ...
- 【JavaScript】修改图片src属性切换图片
今天做项目时其中一个环节需要用到js修改图片src属性切换图片,现在来记录一下 以下是示例: html <img src="/before.jpg" id="img ...
- North American Invitational Programming Contest (NAIPC) 2017
(待补) A. Pieces of Parentheses 将括号处理完成后排序,方式参加下面的博客.然后做一遍背包即可. 2018 Multi-University Training Contest ...
- SOA:面向服务编程——竹子整理
.net中如webservice,wcf,webapi,均可作为服务层,单独部署,而界面UI则部署在另一台服务器上,所有的业务逻辑均在服务层的业务层中进行. 这样一来,我们的UI其实就可以不限制语言, ...
- Python文件与异常处理
文件读写 使用python的BIF(build in function)open()进行文件读写操作 # 1.打开文件 data = open(file_name,'w') # 读取模式有很多种,主要 ...
- 15,scrapy中selenium的应用
引入 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生如果直接用scrapy对其url发请求,是获取不到那部分动态加载出来的数据值,但是通过观察会发现,通过浏览器 ...
- Python虚拟机类机制之descriptor(三)
从slot到descriptor 在Python虚拟机类机制之填充tp_dict(二)这一章的末尾,我们介绍了slot,slot包含了很多关于一个操作的信息,但是很可惜,在tp_dict中,与__ge ...
- net user
net user 编辑 Net User命令是一个DOS命令,必须在Windows nt以上系统的MS-DOS模式下运行,所以首先要进入MS-DOS模式:选择“开始”菜单的“附件”选项的子选项“命令提 ...