传送门

关于这题答案,因为在所有行,往后跳到任意一行的\(w_{i,j}\)都是一样的,所以可以算出跳\(x\)步的答案然后乘上\(\binom{l}{x}\),也就是枚举跳到了哪些行

如果记跳x步的方案是\(f_x\),\(n=1\)时,\(f_x={w_{1,1}}^x\);\(n>1\)时,因为n很小,转移可以写成矩阵,然后矩阵快速幂后就是初始矩阵乘转移矩阵的第一行第\(y\)列的值

后面记\(w\)为对应的转移矩阵,\(a\)为初始矩阵(省略下标\(_{(1,y)}\))

我们把答案式子列出来\(ans_x=\sum_{i=0}^{l}[i\mod\ k=x]aw^i\binom{l}{i}\)

然后可以快乐的推导\(ans_x=\sum_{i=0}^{l}[k|(i-x)]aw^i\binom{l}{i}\)

那个条件是单位根反演,即\([n|m]=>[\frac{1}{n}\sum_{i=0}^{n-1}\omega_{n}^{im}=1]\),所以可以得到

\(ans_x=\sum_{i=0}^{l}\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{j(i-x)}aw^i\binom{l}{i}\)

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{-jx}\sum_{i=0}^{l}\omega_{k}^{ji}aw^i\binom{l}{i}\)

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{-jx}\sum_{i=0}^{l}a(\omega_{k}^jw)^i\binom{l}{i}\)

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{-jx}a\sum_{i=0}^{l}\binom{l}{i}(\omega_{k}^jw)^iI^{l-i}\)

二项式定理得

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{-jx}a(\omega_{k}^jw+I)^l\)

后面那个东西可以预处理,第\(i\)项记为\(g_i\),然后我们要求

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{-jx}g_j\)

可以看到\(-jx\)比较麻烦,不过\(ij=\frac{(i+j)^2}{2}-\frac{i^2}{2}-\frac{j^2}{2}\),但是\(\omega_{k}\)不一定有二次剩余,所以可以这样\(ij=\binom{i+j}{2}-\binom{i}{2}-\binom{j}{2}\),然后

\(ans_x=\frac{1}{k}\sum_{j=0}^{k-1}\omega_{k}^{\binom{j-x}{2}-\binom{j}{2}-\binom{-x}{2}}g_j\)

\(ans_x=\frac{1}{k}\omega_{k}^{-\binom{-x}{2}}\sum_{j=0}^{k-1}\omega_{k}^{\binom{j-x}{2}}\omega_{k}^{-\binom{j}{2}}g_j\)

然后是个卷积形式,就可以\(MTT\)算了

注意优化常数,例如矩乘少一点取模,还有就是\(FFT\)可以优化一下长度

// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db long double using namespace std;
const int N=1e5+100,M=270000+10;
const db pi=acos(-1);
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,m,l,x,y,mod,sqtm,wm,wk,f[N];
int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;} return an;}
int inv(int a){return fpow(a,mod-2);}
LL c2(int a){return 1ll*(a)*(a-1)/2;}
int getw(int mod)
{
int st[20],tp=0,xx=mod-1,phim=xx,lim=sqrt(xx);
for(int i=2;xx>1&&i<=lim;++i)
if(xx%i==0)
{
st[++tp]=i;
while(xx%i==0) xx/=i;
}
if(xx>1) st[++tp]=xx;
for(int g=2;;++g)
{
bool o=1;
for(int j=1;j<=tp&&o;++j)
o=fpow(g,phim/st[j])>1;
if(o) return g;
}
}
struct matrix
{
int a[3][3];
matrix(){memset(a,0,sizeof(a));}
matrix operator + (const matrix &bb) const
{
matrix an;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
an.a[i][j]=(a[i][j]+bb.a[i][j])%mod;
return an;
}
matrix operator * (const int &bb) const
{
matrix an;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
an.a[i][j]=1ll*a[i][j]*bb%mod;
return an;
}
matrix operator * (const matrix &bb) const
{
matrix an;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
{
LL nw=0;
for(int k=0;k<3;++k)
nw+=1ll*a[i][k]*bb.a[k][j];
an.a[i][j]=nw%mod;
}
return an;
}
matrix operator ^ (const int &bb) const
{
int b=bb;
matrix an,a=*this;
for(int i=0;i<3;++i) an.a[i][i]=1;
while(b)
{
if(b&1) an=an*a;
a=a*a,b>>=1;
}
return an;
}
}maa,mab,me;
int nn,rdr[M];
struct comp
{
db r,i;
comp(){}
comp(db nr,db ni){r=nr,i=ni;}
comp operator + (const comp &bb) const {return comp(r+bb.r,i+bb.i);}
comp operator - (const comp &bb) const {return comp(r-bb.r,i-bb.i);}
comp operator * (const comp &bb) const {return comp(r*bb.r-i*bb.i,r*bb.i+i*bb.r);}
}p1[M],p2[M],p3[M],p4[M],p5[M],p6[M],p7[M];
void fft(comp *a,int op)
{
comp x,y,w;
for(int i=0;i<nn;++i)
if(i<rdr[i]) swap(a[i],a[rdr[i]]);
for(int i=1;i<nn;i<<=1)
{
comp ww=comp(cos(pi/i),op*sin(pi/i));
for(int j=0;j<nn;j+=i<<1)
{
w=comp(1,0);
for(int k=0;k<i;++k,w=w*ww)
x=a[j+k],y=a[j+k+i]*w,a[j+k]=x+y,a[j+k+i]=x-y;
}
}
if(op==-1) for(int i=0;i<nn;++i) a[i].r/=nn;
}
void mul(int *a,int *b)
{
for(int i=0;i<nn;++i)
p1[i]=comp(a[i]/sqtm,0),p2[i]=comp(a[i]%sqtm,0);
for(int i=0;i<nn;++i)
p3[i]=comp(b[i]/sqtm,0),p4[i]=comp(b[i]%sqtm,0);
fft(p1,1),fft(p2,1),fft(p3,1),fft(p4,1);
for(int i=0;i<nn;++i) p5[i]=p1[i]*p3[i],p6[i]=p1[i]*p4[i]+p2[i]*p3[i],p7[i]=p2[i]*p4[i];
fft(p5,-1),fft(p6,-1),fft(p7,-1);
for(int i=0;i<nn;++i)
a[i]=((LL)(p5[i].r+0.5)%mod*sqtm%mod*sqtm%mod+(LL)(p6[i].r+0.5)%mod*sqtm%mod+(LL)(p7[i].r+0.5)%mod)%mod;
}
int aa[M],bb[M],an[N]; int main()
{
n=rd(),m=rd(),l=rd(),x=rd()-1,y=rd()-1,mod=rd();
sqtm=sqrt(mod);
for(int i=0;i<3;++i) me.a[i][i]=1;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
mab.a[i][j]=rd();
maa.a[0][x]=1;
wm=getw(mod),wk=fpow(wm,(mod-1)/m);
for(int i=0,j=1;i<m;++i,j=1ll*j*wk%mod)
f[i]=(maa*((mab*j+me)^l)).a[0][y];
int ll=0,invwk=inv(wk);
nn=1;
while(nn<(m<<2)) nn<<=1,++ll;
for(int i=0;i<nn;++i) rdr[i]=(rdr[i>>1]>>1)|((i&1)<<(ll-1));
for(int i=0;i<=m+m;++i) aa[i]=fpow(wk,(c2(i-m)+mod-1)%(mod-1));
for(int i=0;i<m;++i) bb[m-i]=1ll*f[i]*fpow(invwk,(c2(i)+mod-1)%(mod-1))%mod;
mul(aa,bb);
int invk=inv(m);
for(int i=0;i<m;++i) an[i]=1ll*invk*fpow(invwk,(c2(-i)+mod-1)%(mod-1))%mod*aa[m+m-i]%mod;
for(int i=0;i<m;++i) printf("%d\n",an[i]);
return 0;
}

luogu P5293 [HNOI2019]白兔之舞的更多相关文章

  1. HNOI2019 白兔之舞 dance

    HNOI2019 白兔之舞 dance 显然\(n=3\)就是\(n=1\)的扩展版本,先来看看\(n=1\)怎么做. 令\(W=w[1][1]\),显然答案是:\(ans_t=\sum_{i\mod ...

  2. 【Luogu5293】[HNOI2019] 白兔之舞

    题目链接 题目描述 略 Sol 考场上暴力 \(O(L)\) 50分真良心. 简单的推一下式子,对于一个 t 来说,答案就是: \[\sum_{i=0}^{L} [k|(i-t)] {L\choose ...

  3. [HNOI2019]白兔之舞

    memset0 多合一无聊题 mod k=t,并且k是p-1的约数 单位根反演石锤了. 所以直接设f[i]表示走i步的方案数, 然后C(L,i)分配位置,再A^i进行矩乘得到f[i] 变成生成函数F( ...

  4. [HNOI2019]白兔之舞(矩阵快速幂+单位根反演)

    非常抱歉,这篇文章鸽了.真的没时间写了. #include<bits/stdc++.h> using namespace std; typedef long long ll; #defin ...

  5. Solution -「HNOI 2019」「洛谷 P5293」白兔之舞

    \(\mathcal{Description}\)   Link.   不想概括题意.jpg \(\mathcal{Solution}\)   定义点集 \(S_c=\{(u,v)|v=c\}\):第 ...

  6. Loj 3058. 「HNOI2019」白兔之舞

    Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...

  7. 「HNOI 2019」白兔之舞

    一道清真的数论题 LOJ #3058 Luogu P5293 题解 考虑$ n=1$的时候怎么做 设$ s$为转移的方案数 设答案多项式为$\sum\limits_{i=0}^L (sx)^i\bin ...

  8. 「loj3058」「hnoi2019」白兔之舞

    题意 有一个\((L+1)*n\) 的网格图,初始时白兔在\((0,X)\) , 每次可以向横坐标递增,纵坐标随意的位置移动,两个位置之间的路径条数只取决于纵坐标,用\(w(i,j)\) 表示,如果要 ...

  9. LOJ3058. 「HNOI2019」白兔之舞 [DP,MTT]

    LOJ 前置知识:任意长度NTT 普通NTT只能做\(2^k\)的循环卷积,尝试扩展成长度为\(n\)的循环卷积,保证模意义下\(\omega_n\)存在. 不管怎样还是要算点值.推式子: \[ \b ...

随机推荐

  1. nginx上配置phpmyadmin

    Nginx配置phpmyadmin流程如下: 一.准备软件和环境(这里我以ubuntu16.04为例) 1.安装php7.1 sudo LC_ALL=C.UTF- add-apt-repository ...

  2. C语言作业评价标准

    C语言作业评价标准 作业内容: 每周作业分为基础作业.挑战作业和预习作业: 基础作业为本周所学内容的巩固: 挑战作业包括但不仅限于所学知识的综合运用: 预习作业为下周所学内容的任务单,要求必须在课前完 ...

  3. localStorage sessionStorage 增强版

    1. 保留了localStorage sessionStorage的(setItem getItem removeItem clear key)api,使用上几乎差不多 2. 增强了setItem方法 ...

  4. 基于aws api gateway的asp.net core验证

    本文是介绍aws 作为api gateway,用asp.net core用web应用,.net core作为aws lambda function. api gateway和asp.net core的 ...

  5. iOS开发基础-九宫格坐标(3)之Xib

    延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍  Xib 和 storyboard 的比较: 1) X ...

  6. .Net Core应用框架Util介绍(六)

    前面介绍了Util是如何封装以降低Angular应用的开发成本. 现在把关注点移到服务端,本文将介绍分层架构各构造块及基类,并对不同层次的开发人员应如何进行业务开发提供一些建议. Util分层架构介绍 ...

  7. .NET 开源项目 Polly 介绍

    今天介绍一个 .NET 开源库:Polly,它是支持 .NET Core 的,目前在 GitHub 的 Star 数量已经接近 5 千,它是一个强大且实用的 .NET 库. Polly 介绍 官方对 ...

  8. EQueue

    EQueue 2.3.2版本发布(支持高可用) - dotNET跨平台 - CSDN博客https://blog.csdn.net/sD7O95O/article/details/78097193 E ...

  9. Android技术框架——Dagger2

    Dagger2 是一个Android依赖注入框架.没错依赖注入,学习过spring的同学看到这词,应该是挺熟悉的.当然既然是Android的课题,我们就来聊聊Dagger2 ,android开发当前非 ...

  10. Python——高阶函数——map filter zip

    一.map函数 1.作用:它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 2.实例 def f(x): return x* ...