Atcoder 题面传送门 & 洛谷题面传送门

Yet another AGC F,然鹅这次就没能自己想出来了……

首先需注意到题目中有一个条件叫做“黑格子组成的连通块是四联通的”,这意味着我们将所有黑格都替换为题目中 \(H\times W\) 的标准型之后,黑格(标准型)内部是不会对连通块个数产生贡献的,产生贡献的只可能是黑格与黑格之间的边不产生连通块。如果我们记 \(G_{\text{h}}\) 两个标准型横着拼在一起得到的 \(H\times 2W\) 的图形,\(G_{\text{v}}\) 为两个标准型竖着拼在一起得到的 \(2H\times W\) 的图形,那么稍微分析一下即可得到以下性质:

  • 如果 \(G_{\text{h}},G_{\text{v}}\) 中都只有一个连通块,那么最终得到的 \(k\) 级分形也只有一个连通块。因为对于原来的标准型中的相邻两个黑格,由于 \(G_{\text{h}},G_{\text{v}}\) 连通,所以将这两个黑格分别替换为标准型后,这两个黑格所表示的连通块依旧连通,又因为这个标准型本来就是连通图,所以进行一次迭代(将黑格替换为标准型)后,该图中所有黑格表示的标准型都是连通的,也就是说该标准型的二级分形为连通图。又 \(\because G_{\text{h}}\) 连通,仿照上述推理过程可知 \(G_{\text{h}}\) 进行一次迭代后之后,所得的分形仍是连通图,即将该标准型的二级分形左右拼接后,可以得到连通形,\(G_{\text{v}}\) 也同理,如此归纳下去即可证明。
  • 如果 \(G_{\text{h}},G_{\text{v}}\) 中都有两个连通块,那么最终得到的 \(k\) 级分形中有 \(\text{标准型中黑格个数}^{k-1}\) 个黑格,这个好办,\(G_{\text{h}},G_{\text{v}}\) 都有两个连通块,这意味着对于标准型中的任意两个相连的黑格,将它们分别替换为标准型后,彼此之间互不连通,也就是每个黑格各自成一个连通块,记原来的标准型中黑格个数为 \(C\),那么根据之前的推论,二级分形中有 \(C\) 个连通块,\(C^2\) 个黑格,三级分形中有 \(C^2\) 个连通块,\(C^3\) 个黑格,以此类推。

比较棘手的是 \(G_{\text{h}},G_{\text{v}}\) 刚好一个连通,一个不连通的情况。不妨设 \(G_{\text{h}}\) 连通,\(G_{\text{v}}\) 不连通。我们考虑探究一次迭代会对连通块个数产生什么影响。我们考虑使用一个并查集的思想,不妨假设所有黑格替换为的分形都单独成一个连通块,然后将能并的并起来,显然两个黑格表示的连通块能够并起来当且仅当它们左右相邻,而显然左右相邻的格子不会组成环,也就是说每次合并都是合法的,这样减少的连通块个数就是左右相邻的黑格个数,故一次迭代之后连通块的个数,就等于黑格个数减去左右相邻的黑格个数。

考虑怎样计算这个东西,设 \(a_k\) 为 \(k\) 级分形中左右相邻的黑格个数,\(b_k\) 为 \(k\) 级分形中的黑格个数,那么显然可以推出 \(b\) 的递推式 \(b_{k+1}=b_kb_1\),但是推出 \(a\) 的递推式还有些困难。考虑将 \(k\) 级分形替换为 \(k+1\) 级分形后,左右相邻的黑格的来头,显然它可能是一个黑格替换为一个标准型分形后,内部出现左右相邻的黑格,这部分我们是可以计算的,为 \(b_ka_1\),也有可能是本身左右相邻的黑格替换为标准型后,边界上出现左右相邻的黑格,我们发现这东西无法直接表示,那就设一下呗。再设 \(c_k\) 为 \(k\) 级分形中左右拼接的边界上左右相邻的黑格个数,设完之后这东西就很好表示了,为 \(a_kc_1\),即 \(a_{k+1}=b_ka_1+a_kc_1\)。最后考虑 \(c\) 的递推式,显然边界上相邻只可能是原来边界上相邻的黑格被替换为标准型后,每对相邻的黑格新多出 \(c_1\) 对出来,即 \(c_{k+1}=c_kc_1\)。

最后看下数据范围……\(10^{18}\),还有这么多递推式,那显然矩阵快速幂咯。稍微推推即可得到 \(\begin{bmatrix}b_k&a_k\\0&c_k\end{bmatrix}\times\begin{bmatrix}b_1&a_1\\0&c_1\end{bmatrix}=\begin{bmatrix}b_{k+1}&a_{k+1}\\0&c_{k+1}\end{bmatrix}\),即 \(\begin{bmatrix}b_k&a_k\\0&c_k\end{bmatrix}=\begin{bmatrix}b_1&a_1\\0&c_1\end{bmatrix}^k\),快速幂即可。

const int MAXN=1e3;
const int MOD=1e9+7;
int n,m;ll k;
char s[MAXN+5][MAXN+5];
int qpow(int x,ll e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
struct mat{
ll a[2][2];
mat(){memset(a,0,sizeof(a));}
mat operator *(const mat &rhs){
mat ret;
for(int i=0;i<2;i++) for(int j=0;j<2;j++)
for(int k=0;k<2;k++) ret.a[i][j]+=a[i][k]*rhs.a[k][j];
for(int i=0;i<2;i++) for(int j=0;j<2;j++) ret.a[i][j]%=MOD;
return ret;
}
};
int main(){
scanf("%d%d%lld",&n,&m,&k);if(!k) return puts("1"),0;
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
int ud_bor=0,lr_bor=0,ud_ins=0,lr_ins=0,cnt=0;
for(int i=1;i<=m;i++) ud_bor+=(s[1][i]=='#'&&s[n][i]=='#');
for(int i=1;i<=n;i++) lr_bor+=(s[i][1]=='#'&&s[i][m]=='#');
for(int i=1;i<n;i++) for(int j=1;j<=m;j++) ud_ins+=(s[i][j]=='#'&&s[i+1][j]=='#');
for(int i=1;i<=n;i++) for(int j=1;j<m;j++) lr_ins+=(s[i][j]=='#'&&s[i][j+1]=='#');
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt+=(s[i][j]=='#');
// printf("%d %d %d %d %d\n",ud_bor,lr_bor,ud_ins,lr_ins,cnt);
if(!ud_bor&&!lr_bor) printf("%d\n",qpow(cnt,k-1));
else if(ud_bor&&lr_bor) printf("1\n");
else{
mat trs,res;res.a[0][0]=res.a[1][1]=1;--k;
if(ud_bor) trs.a[0][0]=cnt,trs.a[0][1]=ud_ins,trs.a[1][1]=ud_bor;
else trs.a[0][0]=cnt,trs.a[0][1]=lr_ins,trs.a[1][1]=lr_bor;
for(;k;k>>=1,trs=trs*trs) if(k&1) res=res*trs;
printf("%d\n",(res.a[0][0]-res.a[0][1]+MOD)%MOD);
}
return 0;
}

Atcoder Grand Contest 003 F - Fraction of Fractal(矩阵乘法)的更多相关文章

  1. AtCoder Grand Contest 003 F - Fraction of Fractal

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...

  2. AtCoder Grand Contest 003

    AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...

  3. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  4. AtCoder Grand Contest 003 D - Anticube

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_d 题目大意: 给定\(n\)个数\(s_i\),要求从中选出尽可能多的数,满足任意两个数之积 ...

  5. AtCoder Grand Contest 017 F - Zigzag

    题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...

  6. AtCoder Grand Contest 003 E - Sequential operations on Sequence

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...

  7. AtCoder Grand Contest 011 F - Train Service Planning

    题目传送门:https://agc011.contest.atcoder.jp/tasks/agc011_f 题目大意: 现有一条铁路,铁路分为\(1\sim n\)个区间和\(0\sim n\)个站 ...

  8. AtCoder Grand Contest 010 F - Tree Game

    题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...

  9. AtCoder Grand Contest 016 F - Games on DAG

    题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_f 题目大意: 给定一个\(N\)点\(M\)边的DAG,\(x_i\)有边连向\(y_i\) ...

随机推荐

  1. Golang通脉之方法

    方法和接收者 Go语言中的方法(Method)是一种作用于特定类型变量的函数.这种特定类型变量叫做接收者(Receiver).接收者的概念就类似于其他语言中的this或者 self. Go 语言中同时 ...

  2. LeetCode:数组专题

    数组专题 有关数组的一些 leetcode 题,在此做一些记录,不然没几天就忘光光了 二分查找 双指针 滑动窗口 前缀和/差分数组 二分查找 本文内容摘录自公众号labuladong中有关二分查找的文 ...

  3. 安装多个版本的 JDK

    安装多个版本的 JDK 刚刚开始学 Java 的时候安装了 JDK9 版本,后续发现还是 JDK8 使用的多些,而又不想删除原先版本 因此安装两个版本的 JDK 在需要是切换一下即可 1. 安装第一个 ...

  4. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  5. BUAA 2020 软件工程 热身作业

    BUAA 2020 软件工程 热身作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! ...

  6. stm32驱动超声波模块

    下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发. #define HCSR04_PORT GPIOB #define HCSR04_CLK RCC ...

  7. .NET Core TLS 协议指定被我钻了空子~~~

    前言 此前,测试小伙伴通过工具扫描,平台TLS SSL协议支持TLS v1.1,这不安全,TLS SSL协议至少是v1.2以上才行,想到我们早已将其协议仅支持v1.3,那应该非我们平台问题.我依然自信 ...

  8. jQuery常用验证

    1.文本框不能为为空 if ($("#RushStartTime").val() == "") { alert("请输入该产品.."); $ ...

  9. Maven下载、安装、配置

    简介 Maven是一个项目管理工具,主要用于Java平台的项目构建.依赖管理和项目生命周期管理. 当然对于我这样的程序猿来说,最大的好处就是对jar包的管理比较方便,只需要告诉Maven需要哪些jar ...

  10. PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分)

    PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分) 对于给定的最小堆(优先队列),分别实现插入元素和删除堆顶的函数. 函数接口定义: int insertIntoHeap(struct Hea ...