# OpenJudge 1058 Guideposts | BZOJ 3328 PYXFIB

BZOJ 同时被 2 个专栏收录
23 篇文章 0 订阅
1 篇文章 0 订阅

i=0N[K|i](Ni)Gis,t(modP)

Guideposts： 1N1018,1M5,1K5000,1P109 $1\leq N\leq 10^{18},1\leq M\leq 5,1\leq K\leq 5000,1\leq P\leq 10^9$
PYXFIB： 1N1018,M=2,1K2104,1P109 $1\leq N\leq 10^{18},M=2,1\leq K\leq 2\cdot 10^4,1\leq P\leq 10^9$

[K|i] $[K|i]$可以利用单位复根进行构造，显然有

0j<KωijKK=[K|i]

i=0Nj=0K1ωijKK(Ni)Gis,t=1Kj=0K1i=0N(Ni)(ωjKG)is,t=1Kj=0K1i=0N(Ni)(INi(ωjKG)i)s,t=1Kj=0K1(I+ωjKG)Ns,t

#include <cstdio>
#include <cstring>
typedef long long LL;
const int maxn = 5001, maxs = 5, maxp = 10;
int m, len, mod;
LL n;
struct Matrix
{
int r, c, num[maxs][maxs];
Matrix operator + (const Matrix &t) const
{
Matrix ret = {r, c};
for(int i = 0; i < r; ++i)
for(int j = 0; j < c; ++j)
if((ret.num[i][j] = num[i][j] + t.num[i][j]) >= mod)
ret.num[i][j] -= mod;
return ret;
}
Matrix operator * (const Matrix &t) const
{
Matrix ret = {r, t.c};
for(int i = 0; i < r; ++i)
for(int j = 0; j < c; ++j)
for(int k = 0; k < t.c; ++k)
ret.num[i][k] = (ret.num[i][k] + (LL)num[i][j] * t.num[j][k]) % mod;
return ret;
}
Matrix operator * (const int &t) const
{
Matrix ret = {r, c};
for(int i = 0; i < r; ++i)
for(int j = 0; j < c; ++j)
ret.num[i][j] = (LL)num[i][j] * t % mod;
return ret;
}
Matrix pow(LL k)
{
Matrix ret = {r, r}, tmp = *this;
for(int i = 0; i < r; ++i)
ret.num[i][i] = 1;
for( ; k; k >>= 1, tmp = tmp * tmp)
if(k & 1)
ret = ret * tmp;
return ret;
}
} I, A, B;
int mod_inv(int x)
{
return x <= 1 ? x : mod - mod / x * (LL)mod_inv(mod % x) % mod;
}
int mod_pow(int x, int k)
{
int ret = 1;
for( ; k; k >>= 1, x = (LL)x * x % mod)
if(k & 1)
ret = (LL)ret * x % mod;
return ret;
}
int origin()
{
int cnt = 0, tmp = mod - 1;
static int fact[maxp];
for(int i = 2; (LL)i * i <= tmp; ++i)
if(tmp % i == 0)
{
fact[cnt++] = i;
do tmp /= i; while(tmp % i == 0);
}
if(tmp > 1)
fact[cnt++] = tmp;
for(int ori = 2; ; ++ori)
{
bool flag = 1;
for(int i = 0; i < cnt && flag; ++i)
flag &= mod_pow(ori, (mod - 1) / fact[i]) != 1;
if(flag)
return ori;
}
}
int main()
{
for(int tot, sta, ter, w; scanf("%d%lld%d%d", &m, &n, &len, &mod) == 4; )
{
memset(&I, 0, sizeof(Matrix));
I.r = I.c = m;
for(int i = 0; i < m; ++i)
I.num[i][i] = 1;
memset(&A, 0, sizeof(Matrix));
A.r = A.c = m;
scanf("%d%d%d", &tot, &sta, &ter);
for(int u, v; tot--; )
{
scanf("%d%d", &u, &v);
++A.num[--u][--v];
}
memset(&B, 0, sizeof(Matrix));
B.r = B.c = m;
w = mod_pow(origin(), (mod - 1) / len);
for(int i = 0, ww = 1; i < len; ++i, ww = (LL)ww * w % mod)
B = B + (A * ww + I).pow(n);
printf("%d\n", (int)((LL)B.num[--sta][--ter] * mod_inv(len) % mod));
}
return 0;
}
• 0
点赞
• 0
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

08-11 3408
04-30 160

01-19 2558
08-09 1万+
09-02 2053
12-07 42
11-09 702
05-12 6960
04-16 1052
06-07 1万+
12-05 1万+