「HNOI 2019」白兔之舞
一道清真的数论题
题解
考虑$ n=1$的时候怎么做
设$ s$为转移的方案数
设答案多项式为$\sum\limits_{i=0}^L (sx)^i\binom{L}{i}=(sx+1)^L$
答案相当于这个多项式模$ k$的各项系数的和
发现这和LJJ学二项式定理几乎一模一样
然而直接搞是$ k^2$的,无法直接通过本题
以下都用$ w$表示$ k$次单位根
设$ F_i$为次数模$ k$为$ i$的项的系数和
单位根反演一下得到$F(i)=\sum\limits_{j=0}^{k-1}w^{-ij}(sw^j+1)^L$
组合数有个非常优美的性质
$$ij=\binom{i+j}{2}-\binom{i}{2}-\binom{j}{2}$$
推波式子
$$
\begin{aligned}
F(i)&=\sum_{j=0}^{k-1}w^{-ij}(sw^j+1)^L\\
&=\sum_{j=0}^{k-1}w^{\binom{i}{2}+\binom{j}{2}-\binom{i+j}{2}}(sw^j+1)^L\\
&=w^\binom{i}{2}\sum_{j=0}^{k-1}w^{-\binom{i+j}{2}}w^\binom{j}{2}(sw^j+1)^L\\
\end{aligned}
$$
发现这是一个差卷积的形式
扔一个$ MTT$上去就能拿那$ 40$分了
考虑$ n>1$的情况
相当于把$ s$从一个数变成了矩阵,把$ 1$变成单位矩阵
$ (sw^j+1)^L$这个矩阵我们只需要关注一个位置上的值
因此可以乘出来然后取[x][y]这个位置上的数即可
这样就可以通过此题
复杂度:大常数单 $\log$
代码
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,cnt,p,L;
int w[],val[];
int f[],g[],F[];
int ksm(int x,int y=p-){
int ans=;
for(;y;y>>=,x=1ll*x*x%p)if(y&)ans=1ll*ans*x%p;
return ans;
}
struct mat{
ll a[][];
void print(){
for(rt i=;i<n;i++)for(rt j=;j<n;j++)cout<<a[i][j]<<" \n"[j==n-];
}
inline mat operator*(const mat s)const{
mat ret={};
for(rt i=;i<n;i++)
for(rt k=;k<n;k++)
for(rt j=;j<n;j++)
(ret.a[i][j]+=a[i][k]*s.a[k][j]);
for(rt i=;i<n;i++)for(rt j=;j<n;j++)ret.a[i][j]%=p;
return ret;
}
mat operator*(const int s)const{
mat ret;
for(rt i=;i<n;i++)
for(rt j=;j<n;j++)
ret.a[i][j]=a[i][j]*s%p;
return ret;
}
mat operator+(const mat s)const{
mat ret;memset(ret.a,,sizeof(ret.a));
for(rt i=;i<n;i++)
for(rt j=;j<n;j++)
ret.a[i][j]=(a[i][j]+s.a[i][j])%p;
return ret;
} }I,zy;
mat ksm(mat x,int y){
mat ans=I;
for(;y;y>>=,x=x*x)if(y&)ans=ans*x;
return ans;
}
int V(int x){
return 1ll*x*(x-)/%k;
}
const double PI=acos(-1.0);
struct cp{
double x,y;
cp operator +(const cp &s)const{return {x+s.x,y+s.y};}
cp operator -(const cp &s)const{return {x-s.x,y-s.y};}
cp operator *(const cp &s)const{return {x*s.x-y*s.y,x*s.y+y*s.x};}
}W[][<<],A[],B[],C[],D[];
int R[];
void FFT(const int n,cp *A){
for(rt i=;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
for(rt j=;j<n;j+=){
const cp x=A[j],y=A[j+];
A[j]=x+y,A[j+]=x-y;
}
for(rt i=,s=;i<n;i<<=,s++)
for(rt j=;j<n;j+=i<<)
for(rt k=;k<i;k+=){
cp x=A[j+k],y=W[s][k]*A[i+j+k];
A[j+k]=x+y;A[i+j+k]=x-y;
x=A[j+k+],y=W[s][k+]*A[i+j+k+];
A[j+k+]=x+y;A[i+j+k+]=x-y;
}
}
int yg(int n){
for(rt i=;i<=n;i++){
for(rt j=;j*j<=n;j++)if((n-)%j==)
if(ksm(i,(n-)/j)==)goto end;
return i;end:;
}
}
void subtask(){
w[]=;w[]=ksm(yg(p),(p-)/k);
for(rt i=;i<k;i++)w[i]=1ll*w[i-]*w[]%p;mat s=zy;
for(rt i=;i<k;i++){
g[i]=ksm(s*w[i]+I,L).a[x-][y-]*w[V(i)]%p;
}
for(rt i=;i<k+k;i++)f[i]=w[(k-V(i))%k];
for(rt i=;i<k/;i++)swap(g[i],g[k-i]); n=k+k-;m=k;
int lim=;while(lim<=n+m)lim<<=;
for(rt i=;(<<i)<lim;i++){
W[i][]={,};
W[i][]={cos(PI/(<<i)),sin(PI/(<<i))};
for(rt j=;j<<<i;j++)
if(j%==)W[i][j]={cos(PI*j/(<<i)),sin(PI*j/(<<i))};
else W[i][j]=W[i][j-]*W[i][];
} for(rt i=;i<=n;i++){
A[i].x=f[i]>>;
A[i].y=f[i]&;
}
for(rt i=;i<=m;i++){
B[i].x=g[i]>>;
B[i].y=g[i]&;
}
for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|(i&)*(lim>>);
FFT(lim,A);FFT(lim,B);
for(rt i=;i<lim;i++){
const int pl=(lim-)&(lim-i);
const cp ca={A[pl].x,-A[pl].y},cb={B[pl].x,-B[pl].y};
const cp a=(A[i]+ca)*(cp){0.5,},b=(A[i]-ca)*(cp){,-0.5},
c=(B[i]+cb)*(cp){0.5,},d=(B[i]-cb)*(cp){,-0.5};
C[pl]=a*c+a*d*(cp){,};D[pl]=b*c+b*d*(cp){,};
}
FFT(lim,C);FFT(lim,D);
for(rt i=k;i<k+k;i++){
const int vv=1ll*w[V(i-k)]*ksm(k,p-)%p;
ll a=C[i].x/lim+0.5,b=C[i].y/lim+0.5,c=D[i].x/lim+0.5,d=D[i].y/lim+0.5;
a=((a%p)<<)+(((b+c)%p)<<)+d;a=(a%p+p)%p;
writeln(1ll*a*vv%p);
}
exit();
}
int jc[],njc[],inv[],ff[][],ans[];
int c(int x,int y){
return 1ll*jc[x]*njc[y]%p*njc[x-y]%p;
}
void bl(){
for(rt i=;i<;i++)jc[i]=njc[i]=inv[i]=;
for(rt i=;i<=L;i++){
jc[i]=1ll*jc[i-]*i%p;
inv[i]=1ll*inv[p%i]*(p-p/i)%p;
njc[i]=1ll*njc[i-]*inv[i]%p;
}
ff[][x-]=;if(x==y)ans[]=;
for(rt i=;i<=L;i++)
for(rt j=;j<n;j++){
for(rt k=;k<n;k++)
(ff[i][j]+=1ll*zy.a[k][j]*ff[i-][k]%p)%=p;
if(j==y-)(ans[i%k]+=1ll*ff[i][j]*c(L,i)%p)%=p;
}
for(rt i=;i<k;i++)writeln(ans[i]);exit();
}
int main(){
cin>>n>>k>>L>>x>>y>>p;
for(rt i=;i<n;i++)
for(rt j=;j<n;j++)
cin>>zy.a[i][j];
if(L<=)bl();
for(rt i=;i<n;i++)I.a[i][i]=;
subtask();
return ;
}
「HNOI 2019」白兔之舞的更多相关文章
- LOJ#3054. 「HNOI 2019」鱼
LOJ#3054. 「HNOI 2019」鱼 https://loj.ac/problem/3054 题意 平面上有n个点,问能组成几个六个点的鱼.(n<=1000) 分析 鱼题,劲啊. 容易想 ...
- Solution -「HNOI 2019」「洛谷 P5293」白兔之舞
\(\mathcal{Description}\) Link. 不想概括题意.jpg \(\mathcal{Solution}\) 定义点集 \(S_c=\{(u,v)|v=c\}\):第 ...
- Loj 3058. 「HNOI2019」白兔之舞
Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...
- 「WC 2019」数树
「WC 2019」数树 一道涨姿势的EGF好题,官方题解我并没有完全看懂,尝试用指数型生成函数和组合意义的角度推了一波.考场上只得了 44 分也暴露了我在数数的一些基本套路上的不足,后面的 \(\ex ...
- #3146. 「APIO 2019」路灯
#3146. 「APIO 2019」路灯 题目描述 一辆自动驾驶的出租车正在 Innopolis 的街道上行驶.该街道上有 \(n + 1\) 个停车站点,它们将街道划分成了 \(n\) 条路段.每一 ...
- #3145. 「APIO 2019」桥梁
#3145. 「APIO 2019」桥梁 题目描述 圣彼得堡市内所有水路长度总和约 282 千米,市内水域面积占城市面积的 7%.--来自维基百科 圣彼得堡位于由 \(m\) 座桥梁连接而成的 \(n ...
- #3144. 「APIO 2019」奇怪装置
#3144. 「APIO 2019」奇怪装置 题目描述 考古学家发现古代文明留下了一种奇怪的装置.该装置包含两个屏幕,分别显示两个整数 \(x\) 和 \(y\). 经过研究,科学家对该装置得出了一个 ...
- 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)
[题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...
- 「loj3058」「hnoi2019」白兔之舞
题意 有一个\((L+1)*n\) 的网格图,初始时白兔在\((0,X)\) , 每次可以向横坐标递增,纵坐标随意的位置移动,两个位置之间的路径条数只取决于纵坐标,用\(w(i,j)\) 表示,如果要 ...
随机推荐
- python学习笔记4_类和更抽象
python学习笔记4_类和更抽象 一.对象 class 对象主要有三个特性,继承.封装.多态.python的核心. 1.多态.封装.继承 多态,就算不知道变量所引用的类型,还是可以操作对象,根据类型 ...
- 转自阿里云邪-如何从小白成长为 Apache Committer?
http://wuchong.me/blog/2019/02/12/how-to-become-apache-committer/ 过去三年,我一直在为 Apache Flink 开源项目贡献,也在两 ...
- Vue笔记(props和 mounted)
1.mounted 1.1mounted中使用$nextTick会导致页面挂掉 mounted() { // 页面卡死 this.$nextTick(() => { this.setUrl() ...
- 项目中遇到angular时间插件datetinepicker汉化问题
问题描述: 测试需要中文的时间插件: 参考资料: angularjs封装bootstrap官网的时间插件datetimepicker https://www.cnblogs.com/cynthia-w ...
- yaml的用法
yaml是用来读配置文件的. 一般用yaml或者yml结尾创建文件,格式:key: value.然后在用的时候,像打开文件一样读,返回数据可直接转为字典 使用的时候必须先安装模块并导入.安装:pip ...
- In action "Setting JDBC driver jar location unix [Set a variable]" (screen "Select a Database [Configurable banner form]"), property "Script":
java.lang.Exception: JDBC Driver Jar not found. Looking for: /u01/oracle/GG_Director/ERROR: Unresolv ...
- Doctype知识点总结
DOCTYPE是document type (文档类型) 的缩写.<!DOCTYPE >声明位于文档的最前面,处于标签之前,它不是html标签.主要作用是告诉浏览器的解析器使用哪种HTML ...
- 零代码第一步,做个添加数据的服务先。node.js + mysql
node.js + mysql 实现数据添加的功能.万事基于服务! 增删改查之添加数据. 优点:只需要设置一个json文件,就可以实现基本的添加功能,可以视为是零代码. 添加数据的服务实现的功能: 1 ...
- neutron二
第四篇neutron— 网络实践 一.虚拟机获取 ip: 用 namspace 隔离 DHCP 服务 Neutron 通过 dnsmasq 提供 DHCP 服务,而 dnsmasq 通过 ...
- (light oj 1306) Solutions to an Equation 扩展欧几里得算法
题目链接:http://lightoj.com/volume_showproblem.php?problem=1306 You have to find the number of solutions ...