题目:https://loj.ac/problem/3058

先考虑 n=1 怎么做。令 a 表示输入的 w[1][1] 。

  \( ans_t = \sum\limits_{i=0}^{L}C_{L}^{i} a^i [ k|(i-t) ] \)

     \(= \frac{1}{k}\sum\limits_{i=0}^{L}C_{L}^{i} a^i \sum\limits_{j=0}^{k-1} w_{k}^{j*(i-t)} \)

     \(= \frac{1}{k}\sum\limits_{j=0}^{k-1}w_{k}^{-j*t} \sum\limits_{i=0}^{L}C_{L}^{i} a^i w_{k}^{i*j} \)

     \(= \frac{1}{k}\sum\limits_{j=0}^{k-1}w_{k}^{-j*t} (1+a*w_{k}^{j})^{L} \)

  这样是 k2 的,就不会了……

  考虑卷积。把 -j*t 拆成只和 j 有关的与只和 t 或者 t+j 、t-j 有关的。

  注意到 \( j*t = C_{j+t}^{2} - C_{t}^{2} - C_{j}^{2} \) 。考虑 j*t 表示从 j 个里选一个、再从 t 个里选一个;表示成从 (j+t) 里选两个,再减去不合法的,即从 j 个里选了两个或从 t 个里选了两个。

  \( ans_t = \frac{1}{k}\sum\limits_{j=0}^{k}w_{k}^{-\binom{j+t}{2}+\binom{j}{2}+\binom{t}{2}} (1+a*w_{k}^{j})^{L} \)

  最后那个部分只和 j 有关。所以令 \( c_j = (1+a*w_{k}^{j})^{L} \)

     \(= \frac{ w_{k}^{\binom{t}{2}} }{k}\sum\limits_{j=0}^{k-1}w_{k}^{\binom{i}{2}} c_j * w_{k}^{-\binom{j+t}{2}} \)

  然后可以卷积。

  如果 n>1 ,用矩阵表示 “从 x 用 i 步走到 y ”的方案!仍然要乘组合数。

  也就是除了 \( c_j = ( I + A*w_{k}^{j} )^{L} [x,y] \) 之外都没变。其中 A 是输入的矩阵,[x,y] 表示取矩阵的第 x 行第 y 列的值作为 \( c_j \) 。

  给矩阵乘一个数字,是给其每个位置都乘。

  不开 long double 会变成 0 分。

  复习 MTT 。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db long double
#define ll long long
using namespace std;
const int N=(<<)+; const db pi2=acos(-)*;
int n,k,L,x,y,mod,G,bs,len,r[N],c[N],f[N],g[N],wn[N];
int upt(int x){while(x>=mod)x-=mod;while(x<)x+=mod;return x;}
int pw(int x,int k)
{int ret=;while(k){if(k&)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=;}return ret;} struct cpl{
db x,y;
cpl(db x=,db y=):x(x),y(y) {}
cpl operator+ (const cpl &b)const{return cpl(x+b.x,y+b.y);}
cpl operator- (const cpl &b)const{return cpl(x-b.x,y-b.y);}
cpl operator* (const cpl &b)const
{return cpl(x*b.x-y*b.y,x*b.y+y*b.x);}
cpl operator/ (const db &b)const{return cpl(x/b,y/b);}
}Ta[N],Tb[N],P[N],Q[N];
cpl cnj(cpl a){return cpl(a.x,-a.y);}
struct Mtr{
int a[][];
Mtr(){memset(a,,sizeof a);}
Mtr operator* (const Mtr &b)const
{
Mtr c;
for(int i=;i<n;i++)
for(int k=;k<n;k++)
for(int j=;j<n;j++)
c.a[i][j]=(c.a[i][j]+(ll)a[i][k]*b.a[k][j])%mod;
return c;
}
Mtr operator* (const int &b)const
{
Mtr c;
for(int i=;i<n;i++)
for(int j=;j<n;j++)c.a[i][j]=(ll)a[i][j]*b%mod;
return c;
}
Mtr operator+ (const Mtr &b)const
{
Mtr c;
for(int i=;i<n;i++)
for(int j=;j<n;j++)c.a[i][j]=upt(a[i][j]+b.a[i][j]);
return c;
}
}A,tA,tA2,I;
namespace get_G{
int p[],tot;
void solve()
{
int k=mod-;
for(int i=;i*i<=k;i++)
if(k%i==){ p[++tot]=(mod-)/i; while(k%i==)k/=i;}
for(int i=;;i++)
{
bool fg=;
for(int j=;j<=tot;j++)
if(pw(i,p[j])==){fg=;break;}
if(!fg){G=i;break;}
}
}
}
void fft(cpl *a,bool fx)
{
for(int i=;i<len;i++)
if(i<r[i])swap(a[i],a[r[i]]);
for(int R=;R<=len;R<<=)
{
cpl wn=cpl(cos(pi2/R),fx?-sin(pi2/R):sin(pi2/R));
for(int i=,m=R>>;i<len;i+=R)
{
cpl w=cpl(,);
for(int j=;j<m;j++,w=w*wn)
{
cpl x=a[i+j],y=w*a[i+m+j];
a[i+j]=x+y; a[i+m+j]=x-y;
}
}
}
if(!fx)return;
for(int i=;i<len;i++)a[i]=a[i]/len;
}
void MTT(int *a,int *b,int n,int m,int *c)
{
bs=sqrt(mod); cpl ta,tb,tc,td;
for(len=;len<=n+m;len<<=);
for(int i=,j=len>>;i<len;i++)
r[i]=(r[i>>]>>)+((i&)?j:);
for(int i=;i<=n;i++) P[i]=cpl(a[i]/bs,a[i]%bs);
for(int i=;i<=m;i++) Q[i]=cpl(b[i]/bs,b[i]%bs);
fft(P,); fft(Q,);
P[len]=P[]; Q[len]=Q[];
for(int i=;i<len;i++)
{
ta=(P[i]+cnj(P[len-i]))*cpl(0.5,);
tb=(P[i]-cnj(P[len-i]))*cpl(,-0.5);
tc=(Q[i]+cnj(Q[len-i]))*cpl(0.5,);
td=(Q[i]-cnj(Q[len-i]))*cpl(,-0.5);
Ta[i]=ta*tc+ta*td*cpl(,);
Tb[i]=tb*tc+tb*td*cpl(,);
}
fft(Ta,); fft(Tb,);
for(int i=,lm=n+m,bs2=bs*bs;i<=lm;i++)
{
int a2=(ll)(Ta[i].x+0.5)%mod;//%mod
int b2=(ll)(Ta[i].y+0.5)%mod;
int c2=(ll)(Tb[i].x+0.5)%mod;
int d2=(ll)(Tb[i].y+0.5)%mod;
c[i]=((ll)a2*bs2+(ll)(b2+c2)*bs+d2)%mod;
}
}
int main()
{
scanf("%d%d%d%d%d%d",&n,&k,&L,&x,&y,&mod);
get_G::solve(); x--; y--;
for(int i=;i<n;i++)
for(int j=;j<n;j++)scanf("%d",&A.a[i][j]);
wn[]=; wn[]=pw(G,(mod-)/k);
for(int i=;i<=k;i++)wn[i]=(ll)wn[i-]*wn[]%mod;//<=k
for(int i=;i<n;i++)I.a[i][i]=;//
for(int i=;i<k;i++)
{
tA=A*wn[i]+I; tA2=I; int tp=L;//tp=L not i!!!!!
while(tp)
{ if(tp&)tA2=tA2*tA; tA=tA*tA; tp>>=;}
c[i]=tA2.a[x][y];
}
for(int i=;i<k;i++)
f[k--i]=(ll)wn[(ll)i*(i-)/%k]*c[i]%mod;
for(int i=,lm=*(k-);i<=lm;i++)
g[i]=wn[k-(ll)i*(i-)/%k];
MTT(f,g,k-,*(k-),f); int inv=pw(k,mod-);
for(int i=;i<k;i++)
{
int ans=(ll)wn[(ll)i*(i-)/%k]*inv%mod;
ans=(ll)ans*f[k-+i]%mod; printf("%d\n",ans);
}
return ;
}

LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT的更多相关文章

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

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

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

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

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

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

  4. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  5. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  6. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  7. Loj #3057. 「HNOI2019」校园旅行

    Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...

  8. LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分

    题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...

  9. LOJ 3057 「HNOI2019」校园旅行——BFS+图等价转化

    题目:https://loj.ac/problem/3057 想令 b[ i ][ j ] 表示两点是否可行,从可行的点对扩展.但不知道顺序,所以写了卡时间做数次 m2 迭代的算法,就是每次遍历所有不 ...

随机推荐

  1. cron 定时任两种配置方式

    第一种:xml文件方式 <bean id="commonTimer" class="com.course.wx.timer.CommonTimer"> ...

  2. Kestrel web server implementation in ASP.NET Core

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore1x&view ...

  3. ICPC2019上海区域赛 部分题解(正在更新)

    K. Color Graph 题意: 给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少? 思路: 如果一个图中无奇数边的环,那么这个图一定是个二分 ...

  4. 网络流强化-HDU4280

    数组没开够居然显示TLE而不是RE,自己觉得好的优化的方法没什么用…… //http://www.renfei.org/blog/isap.html 带解释的 //https://www.cnblog ...

  5. 【python】含中文字符串截断

    对于含多字节的字符串,进行截断的时候,要判断截断处是几字节字符,不能将多字节从中分割,避免截断后乱码 下面给出utf8和gb18030上的实现, 用任何一种都可以,可以先进行转码,用encode, d ...

  6. linux点滴记录

    以下均为在Ubuntu下实践操作 更改DNS //编辑文件 - “/etc/resolv.conf”,打开“终端应用程序”-“附件” - “终端”,在终端里输入下面的命令: sudo nano /et ...

  7. 合并石子 (区间dp+前缀和)

    [题目描述] N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.计算出将N堆石子合并成一堆的最小得分. [题目链接] http: ...

  8. 标签的增加、删除与复制,动态标签js不生效的解决

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. CSRF——跨站请求伪造

    一.CSRF是什么CSRF,全称:Corss-site request forgery,中文名称:跨站请求伪造.CSRF攻击比XSS攻击更具危险性,被安全界称为“沉睡的巨人”. 二.CSRF可以做什么 ...

  10. canvas 画正方形和圆形

    绘制正方形 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...