Source
Problem
一片 n∗n n ∗ n 的草莓地,每个位置的初始草莓量为横坐标和纵坐标之和。给出熊的初始位置 (sx,sy) ( s x , s y ) ,以及初始移动速度 (dx,dy) ( d x , d y ) ,求这头熊 t t 秒后的位置。每一秒会发生下列3件事:
- 速度增加(
k
k
为该位置的草莓数,即)
- 熊的位置发生移动, Xt=Xt−1+DXt−1+k X t = X t − 1 + D X t − 1 + k
- 每个位置上草莓数 ++ + +
Solution
题目中给出的线性关系很明显,就是要用矩阵快速幂。关键是怎么建立矩阵。
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪XtYtDXtDYtt1⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪211100121100101000010100111110222211⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ ∗⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪Xt−1Yt−1DXt−1DYt−1t−11⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ { X t Y t D X t D Y t t 1 } = { 2 1 1 0 1 2 1 2 0 1 1 2 1 1 1 0 1 2 1 1 0 1 1 2 0 0 0 0 1 1 0 0 0 0 0 1 } ∗ { X t − 1 Y t − 1 D X t − 1 D Y t − 1 t − 1 1 }
上面那个矩阵比较坑的一点就是:题中所给的坐标是 [1,n] [ 1 , n ] ,计算时变成 [0,n−1] [ 0 , n − 1 ] ,而 k=x+y k = x + y 要比正常情况少2( x少1,y少1 x 少 1 , y 少 1 ),所以矩阵第六列的前四行都是2,而不是0。Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<ll> vec; typedef vector<vec>mat; ll n,sx,sy,dx,dy,t; mat mul(mat &A,mat &B,ll M) { mat C(A.size(),vec(B[0].size())); for(int i=0;i<A.size();++i){ for(int k=0;k<B.size();++k){ for(int j=0;j<B[0].size();++j) C[i][j]=(C[i][j]+A[i][k]%M*B[k][j]%M+M)%M; } } return C; } mat qpow(mat A,ll n,ll M) { mat B(A.size(),vec(A.size())); for(ll i=0;i<A.size();++i) B[i][i]=1; while(n>0){ if(n&1) B=mul(B,A,M); A=mul(A,A,M); n>>=1; } return B; } int main() { scanf("%lld%lld%lld%lld%lld%lld",&n,&sx,&sy,&dx,&dy,&t); mat A(6,vec(6)); mat B(6,vec(1)); A[0][0]=A[1][1]=2; A[0][5]=A[1][5]=A[2][5]=A[3][5]=2; A[0][1]=A[0][2]=A[0][4]=A[1][0]=A[1][3]=A[1][4]= A[2][0]=A[2][1]=A[2][2]=A[2][4]=A[3][0]=A[3][1]= A[3][3]=A[3][4]=A[4][4]=A[4][5]=A[5][5]=1; B[0][0]=sx-1;B[1][0]=sy-1;B[2][0]=(dx+n)%n; B[3][0]=(dy+n)%n;B[4][0]=0;B[5][0]=1; A=qpow(A,t,n); B=mul(A,B,n); printf("%lld %lld\n",B[0][0]+1,B[1][0]+1); return 0; }