[CF593E](Strange Calculation and Cats)

  • 题意

题意传送门

  • solution

矩阵加速dp

一般先想dp

一个点的状态等于它自己加上四周没有猫的格子的状态 简单粗暴的dp

然后构造矩阵,长n\(\times\)m,宽\(n\times\)m存储时把两维压成一维存储

若(x1,y1)能到达(x2,y2)则矩阵中即为1否则为0简单粗暴的矩阵

然后每修改一次就重构矩阵,卡速米跳过时间段即可

  • code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define int long long
using namespace std;
const int mod=1000000007;
struct sett{
   int k[50][50];
}ans,base;
int N,n,m,q;
int mp[25][25];
sett mul(sett a,sett b){
    sett c;
    memset(c.k,0,sizeof(c.k));
    for(int i=1;i<=N;i++)
    for(int r=1;r<=N;r++)
    for(int p=1;p<=N;p++)
    c.k[i][r]=(c.k[i][r]+a.k[i][p]*b.k[p][r])%mod;
    return c;
}
void qpow(int b){
    for(;b;b>>=1,base=mul(base,base))if(b&1)ans=mul(base,ans);
}
void build(){
    for(int i=1;i<=N;i++)
    for(int r=1;r<=N;r++){
        int a=((i-1)/m)+1,b=(i-1)%m+1;
        int A=((r-1)/m)+1,B=(r-1)%m+1;
        int dist=abs(A-a)+abs(B-b);
        if(mp[a][b]==0&&mp[A][B]==0&&dist<=1)base.k[i][r]=1;
        else base.k[i][r]=0;
    }
}
signed main(){ 
scanf("%lld%lld%lld",&n,&m,&q);
N=n*m;
ans.k[1][1]=1;
int plk=1;
while(q--){
    build();
   int op,x,y,t;
   scanf("%lld%lld%lld%lld",&op,&x,&y,&t);
   qpow(t-plk);
   plk=t;
   if(op==2)ans.k[(x-1)*m+y][1]=0,mp[x][y]=1;
   if(op==3)ans.k[(x-1)*m+y][1]=0,mp[x][y]=0;
   if(op==1)printf("%lld\n",ans.k[(x-1)*m+y][1]);
}
}
posted @ 2019-02-17 15:53  stepsys  阅读(339)  评论(0编辑  收藏  举报

*/