HNOI2019 白兔之舞 dance


显然\(n=3\)就是\(n=1\)的扩展版本,先来看看\(n=1\)怎么做。

令\(W=w[1][1]\),显然答案是:\(ans_t=\sum_{i\mod k=t}^{L}W^i\binom{L}{i}\)

\(=\sum_{i=0}^{L}[k|(i-t)]W^i\binom{L}{i}\)

这时用一个单位根反演。

回顾一下,单位根是fft时用到的东西,\(\omega_{n}=\cos\frac{2\pi}{n}+\sin\frac{2\pi}{n}i\),在膜\(p\)意义下,求出\(p\)的原根\(g\),\(\omega_{n}=g^{\frac{p-1}{n}}\)。

有一些单位根的性质:

\(\omega_n^i=\omega_n^{i\mod n}\)

\(\omega_n^i=-\omega_n^{i+\frac{n}{2}}\)

单位根反演是这个东西:

\(\frac{1}{n}\sum_{i=0}^{n-1}(\omega_n^k)^i=[n|k]\)。

证明分类讨论:如果\(n|k\),根据上面性质\(\omega_n^k=\omega_n^0=1\);否则这是一个等比数列,公比为\(\omega_{n}^k\),求和为\(\frac{1-\omega_n^{kn}}{1-\omega_n^k}\),上面的这个东西是\(0\)。

将单位根反演套进上面式子,代替\([k|(i-t)]\)。

\(=\sum_{i=0}^{L}\frac{1}{k}\sum_{j=0}^{k-1}(\omega_k^{i-t})^jW^i\binom{L}{i}\)

\(=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{-tj}\sum_{i=0}^{L}W^i\omega_k^{ij}\binom{L}{i}\)

后面这个式子和t没什么关系了,可以统一计算,好像这是个二项式,可以直接算:

\(=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{-tj}\sum_{i=0}^{L}\binom{L}{i}(W\omega_k^j)^i1^{n-i}\)

\(=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{-tj}(\omega_k^jW+1)^L\)

后面这东西只和j有关系,可以提前随便算出来,记为\(c_j\)

\(=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{-tj}c_j\)

然后神仙一波操作,\(-tj=\binom{t}{2}+\binom{j}{2}-\binom{t+j}{2}\)

\(=\frac{1}{k}\sum_{j=0}^{k-1}\omega_k^{\binom{t}{2}+\binom{j}{2}-\binom{t+j}{2}}c_j\)

\(=\frac{1}{k}\omega_k^{\binom{t}{2}}\sum_{j=0}^{k-1}\omega_k^{\binom{j}{2}-\binom{t+j}{2}}c_j\)

\(=\frac{1}{k}\omega_k^{\binom{t}{2}}\sum_{j=0}^{k-1}\omega_k^{\binom{j}{2}}c_j\cdot \omega_k^{-\binom{t+j}{2}}\)

这就是个多项式乘法了,注意t+j那个多项式直接reverse一下,我真的越学越蠢了,不知道这个怎么搞自闭1h

然后因为模数不是ntt模数还要用MTT

好的\(n=1\)做完了,\(n=3\)实际上就是把\(n=1\)的\(W\)换成了输入的矩阵。于是只要修改一下\(c_i\)的求法,先算出\((Begin\cdot(\omega_k^jW)+I)^L\),Begin就是初始矩阵,只有\(1,x\)处是1,再取最终结果需要取的\(1,y\)处的值就行了

#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il ll gi(){
ll x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const double pi=acos(-1);
int m,k,n,x,y,mod,G;
struct matrix{
int s[3][3];matrix(){memset(s,0,sizeof s);}
};
matrix I;
int omega[65539];
il matrix operator+(const matrix&a,const matrix&b){
matrix ret;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j){
ret.s[i][j]=a.s[i][j]+b.s[i][j];
if(ret.s[i][j]>=mod)ret.s[i][j]-=mod;
}
return ret;
}
il matrix operator*(const matrix&a,const matrix&b){
matrix ret;
for(int j=0;j<3;++j)
for(int i=0;i<3;++i)
for(int k=0;k<3;++k)
ret.s[i][k]=(ret.s[i][k]+1ll*a.s[i][j]*b.s[j][k])%mod;
return ret;
}
il matrix operator*(const matrix&a,const int&b){
matrix ret;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
ret.s[i][j]=1ll*a.s[i][j]*b%mod;
return ret;
}
matrix w;
int A[262147],B[262147];
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
il matrix pow(matrix x,int y){
matrix ret=I;
while(y){
if(y&1)ret=ret*x;
x=x*x;y>>=1;
}
return ret;
}
il int getrt(int x){
static int p[50],o=0;
for(int i=2,y=x-1;i<=y;++i)
if(y%i==0){
p[++o]=i;
while(y%i==0)y/=i;
}
for(int g=2;;++g){
bool yes=1;
for(int j=1;j<=o;++j)if(pow(g,(mod-1)/p[j])==1){yes=0;break;}
if(yes)return g;
}
}
typedef std::complex<double> cp;
int rev[262147];cp omg[262147];
cp A1[262147],A2[262147],B1[262147],B2[262147];
il vd fft(cp*A,int n){
for(int i=0;i<n;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
for(int o=1;o<n;o<<=1)
for(cp*p=A;p!=A+n;p+=o<<1)
for(int i=0;i<o;++i){
cp t=omg[n/(o<<1)*i]*p[i+o];
p[i+o]=p[i]-t,p[i]+=t;
}
}
int ans[262147];
int main(){
#ifdef XZZSB
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
I.s[0][0]=I.s[1][1]=I.s[2][2]=1;
m=gi(),k=gi(),n=gi(),x=gi()-1,y=gi()-1,mod=gi();
omega[0]=1;omega[1]=pow(G=getrt(mod),(mod-1)/k);
for(int i=2;i<k;++i)omega[i]=1ll*omega[1]*omega[i-1]%mod;
for(int i=0;i<m;++i)for(int j=0;j<m;++j)w.s[i][j]=gi();
for(int i=0;i<(k<<1|1);++i)A[i]=omega[(k-1ll*i*(i-1)/2%k)%k];
matrix begin;begin.s[0][x]=1;
for(int i=0;i<k;++i)B[i]=1ll*omega[1ll*i*(i-1)/2%k]*(begin*pow(w*omega[i]+I,n)).s[0][y]%mod;
std::reverse(B,B+k+1);
int N=1,lg=0;while(N<(k*3+5))N<<=1,++lg;
for(int i=0;i<N;++i)omg[i]=(cp){cos(i*pi*2/N),sin(i*pi*2/N)};
for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<N;++i)A1[i]=A[i]&32767,A2[i]=A[i]>>15;
for(int i=0;i<N;++i)B1[i]=B[i]&32767,B2[i]=B[i]>>15;
fft(A1,N),fft(B1,N);fft(A2,N),fft(B2,N);
for(int i=0;i<N;++i){
cp _A1=A1[i],_A2=A2[i],_B1=B1[i],_B2=B2[i];
A1[i]=_A1*_B1;A2[i]=_A2*_B2;
B1[i]=_A1*_B2;B2[i]=_A2*_B1;
}
for(int i=0;i<N;++i)omg[i]=(cp){cos(i*pi*2/N),-sin(i*pi*2/N)};
fft(A1,N),fft(B1,N);fft(A2,N),fft(B2,N);
for(int i=0;i<N;++i)A1[i]/=N;
for(int i=0;i<N;++i)A2[i]/=N;
for(int i=0;i<N;++i)B1[i]/=N;
for(int i=0;i<N;++i)B2[i]/=N;
for(int i=0;i<N;++i)A[i]=((ll)(A1[i].real()+0.5)%mod+1073741824ll*(((ll)(A2[i].real()+0.5))%mod)%mod+32768ll*(((ll)(B1[i].real()+0.5))%mod)%mod+32768ll*(((ll)(B2[i].real()+0.5))%mod)%mod)%mod;
int invk=pow(k,mod-2);
for(int i=0;i<k;++i)printf("%lld\n",1ll*A[i+k]*invk%mod*omega[1ll*i*(i-1)/2%k]%mod);
return 0;
}

HNOI2019 白兔之舞 dance的更多相关文章

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

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

  2. luogu P5293 [HNOI2019]白兔之舞

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

  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. Loj 3058. 「HNOI2019」白兔之舞

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

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

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

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

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

  8. LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT

    题目:https://loj.ac/problem/3058 先考虑 n=1 怎么做.令 a 表示输入的 w[1][1] . \( ans_t = \sum\limits_{i=0}^{L}C_{L} ...

  9. 「HNOI 2019」白兔之舞

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

随机推荐

  1. (网页)AngularJS中【Error: [$rootScope:inprog]】的解决办法(转)

    转自CSDN: Error: [$rootScope:inprog] http://errors.angularjs.org/1.5.8/$rootScope/inprog?p0=%24apply 如 ...

  2. U盘内容被病毒隐藏的解决办法(亲测可用)

    前几天用U盘的时候不小心感染上了病毒,用自己的电脑打开后里面只剩下一个U盘的快捷方式,选中显示隐藏文件之后依然没有任何显示,但是查看U盘的属性的时候可以看到,U盘已经使用了300多M,所以就上网查了一 ...

  3. JMeter乱码常见的解决方案

    方法一.直接将JMeter中http请求中Content encoding改为utf-8 方法二.编辑JMeter安装目录:apache-jmeter-3.2\bin中的jmeter.properti ...

  4. Docker容器学习与分享01

    1.什么是容器? 容器技术是一种虚拟化的方案,与传统的虚拟机不同,传统的虚拟机是通过中间层将一台或多台独立的机器虚拟运行于物理硬件之上,而容器是直接运行在操作系统内核之上的用户空间. 所以容器虚拟化又 ...

  5. Alpha版本 - 展示博客

    Alpha版本 - 展示博客 S.W.S.D 成员简介 演示动态图 注册 登录 新建记录 分享记录 修改主页时间查看记录 文章模块 流星模块 修改用户信息(以头像为例) 用户使用概况 预期的典型用户 ...

  6. BeanFactory和ApplicationContext的简单介绍

    引言 Spring通过一个配置文件描述Bean及Bean之间的依赖关系,利用Java语音的反射功能实例化Bean并建立Bean之间的依赖关系.Spring的IoC容器在完成这些底层工作的基础上,还提供 ...

  7. leetcode 395. Longest Substring with At Least K Repeating Characters(高质量题)

    只能说还是太菜,抄的网上大神的做法: idea: mask 的每一位代表该位字母够不够k次,够k次为0,不够为1 对于每一位将其视为起点,遍历至末尾,找到其最大满足子串T的下标max_idx,之后从m ...

  8. Django view 视图

    request.method 判断请求方式 8种 GET : 获取一个页面 POST: 提交数据 PUT : 上传 HEAD: 不用上传就获取数据 DELETE: 删除 Request-URL 标识的 ...

  9. Android事件处理第一节(View对Touch事件的处理)

    http://ipjmc.iteye.com/blog/1694146 在Android里Touch是很常用的事件,尤其实在自定义控件中,要实现一些动态的效果,往往要对Touch进行处理.Androi ...

  10. 基于Redis的INCR实现一个限流器

    模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...