[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 ...
随机推荐
- C++性能优化笔记
最近着手去优化项目中一个模块的性能.该模块是用C++实现,对大量文本数据进行处理. 一开始时,没什么思路,因为不知道性能瓶颈在哪里.于是借助perf工具来对程序进行分析,找出程序的性能都消耗在哪里了. ...
- 安装配置JDK1.8开发环境以及配置java环境变量的步骤
1.安装JDK开发环境 下载网站:http://www.oracle.com/ 开始安装JDK: 修改安装目录如下: 确定之后,单击“下一步”. 注:当提示安装JRE时,可以选择不要安装. 2.配置环 ...
- Vue2.0--14.小白入门教程--实例化多个vue对象,可初始化操作几种方法
课程地址: https://study.163.com/course/courseMain.htm?courseId=1004711010 <!DOCTYPE html> <html ...
- 服务器常说的U是什么意思?
U是英文单词:unit 所说的1U和2U,是服务器的厚度,1U大概是相当于机柜的两个小格子,2U是四个格子.1U大概是4.45厘米(1U=1.75英寸,1英寸=2.54CM).以下这个是图片:
- makefile学习(2)
新建目录如下: ├─include │ integrate.h │ └─src │ integrate.c │ main.c │ makefile │ └─obj obj用于存放object文件. m ...
- String使用方法详解
标准c++中string类函数介绍 注意不是CString 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作 ...
- 关于IDEA 单元测试时 【empty test suite】异常的分析!!
IDEA功能很强大,配置很操蛋,自从用了之后掉了很多坑!!! 这几天要用单元测试,方法完好但是就是一直报empty test suite ,WTF,类找不到 在网上反复的找答案都没有合适 静下心想想, ...
- cacheData
<%@ page language="java" import="java.util.*,com.fiberhome.bcs.appprocess.common.u ...
- 手机端sticker布局,底部按钮在屏幕底部
<template> <div class="product-detail-container"> <div class="detail&q ...
- IOS开发学习笔记022-imageView实现动画
这里要播放的动画是很多张连续的动画,连续播放就会显示出动画效果. 大概过程是: 新建一个single view application ,然后添加一个image View控件到视图.给image vi ...