您的位置:首页 > 其它

[矩阵快速幂] Atcoder AGC003 F. Fraction of Fractal

2017-12-07 20:48 211 查看
很神的题!!!

首先观察一下每次转移

如果初始的图案存在某一行 i,满足行的两个端点为黑,且存在某一列也是满足这样的条件,那么答案就是1,因为原来就连通的黑块转移后的图案也是联通的。

如果行和列都不满足,因为每次转移答案都会乘 x, 那么答案就是 xk−1 ,其中 x 为初始图案中的黑块数量。

如果只有行满足这样的条件(列满足的话转一下图案),

设 x 等于黑块的数量, y 等于初始图像中 ai,j 和 ai,j+1 都为黑的 (i,j) 数量, z 为几行满足上面的条件

那么每次转移就有

x′=x2

y′=xy+yz

z′=z2

这个东西退一下可以知道…

用矩阵转移就好了…

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <assert.h>

using namespace std;

typedef long long ll;

const int N=1010,P=1e9+7;

struct mat{
int a[2][2];
mat(){ a[0][0]=a[1][1]=a[0][1]=a[1][0]=0; }
int *operator [](int x){
return a[x];
}
friend mat operator *(mat a,mat b){
mat c;
c[0][0]=(1LL*a[0][0]*b[0][0]+1LL*a[0][1]*b[1][0])%P;
c[0][1]=(1LL*a[0][0]*b[0][1]+1LL*a[0][1]*b[1][1])%P;
c[1][0]=(1LL*a[1][0]*b[0][0]+1LL*a[1][1]*b[1][0])%P;
c[1][1]=(1LL*a[1][0]*b[0][1]+1LL*a[1][1]*b[1][1])%P;
return c;
}
};

mat u;
int n,m;
char a[N][N],b[N][N];
ll k;

inline int judge(){
for(int i=1;i<=n;i++)
if(a[i][1]=='#' && a[i][m]=='#') return 1;
return 0;
}

inline void turn(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[m-j+1][i]=a[i][j];
swap(n,m); memcpy(a,b,sizeof(a));
}

inline int Pow(int x,ll y){
int ret=1;
for(;y;y>>=1,x=1LL*x*x%P) if(y&1) ret=1LL*ret*x%P;
return ret;
}

inline mat Pow(mat x,ll y){
mat ret=u;
for(;y;y>>=1,x=x*x) if(y&1) ret=ret*x;
return ret;
}

int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
u[0][0]=u[1][1]=1;
scanf("%d%d%lld",&n,&m,&k);
int cnt=0;
for(int i=1;i<=n;i++){
scanf("%s",a[i]+1);
for(int j=1;j<=m;j++)
cnt+=a[i][j]=='#';
}
int A=judge(),B=(turn(),judge()); turn();
if((A && B) || !k) return puts("1"),0;
if(!A && !B) return printf("%d\n",Pow(cnt,k-1)),0;
if(!A) turn();
int c=0,b=0; for(int i=1;i<=n;i++) c+=(a[i][1]=='#' && a[i][m]=='#');
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
b+=(a[i][j]=='#' && a[i][j+1]=='#');
mat w,ans; w[0][0]=cnt; w[0][1]=b; w[1][1]=c;
ans=Pow(w,k-1);
printf("%d\n",(ans[0][0]+P-ans[0][1])%P);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: