[HNOI2019]白兔之舞
多合一无聊题
mod k=t,并且k是p-1的约数
单位根反演石锤了。
所以直接设f[i]表示走i步的方案数,
然后C(L,i)分配位置,再A^i进行矩乘得到f[i]
变成生成函数F(x)=∑f[i]=(A*x+I)^L
求指数mod k=t的系数的和
偏移之后,进行单位根反演
对于t都要求?
NTT
然后WA了
因为要任意模数NTT,。。。。
然后套用全家桶有了9K的代码:
- #include<bits/stdc++.h>
- #define reg register int
- #define il inline
- #define fi first
- #define se second
- #define mk(a,b) make_pair(a,b)
- #define numb (ch^'0')
- using namespace std;
- typedef long long ll;
- template<class T>il void rd(T &x){
- char ch;x=;bool fl=false;
- while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
- for(x=numb;isdigit(ch=getchar());x=x*+numb);
- (fl==true)&&(x=-x);
- }
- template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
- template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
- template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
- //--------------------------------------------------------------------------------------------------------------------//
- namespace Miracle{
- const int N=*;
- int mod,w;
- int X,L,Y,K,G,GI;
- const double Pi=acos(-);
- il int qm(int x,ll y){int ret=;while(y){if(y&) ret=(ll)ret*x%mod;x=(ll)x*x%mod;y>>=;}return ret;}
- il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
- il int sub(int x,int y){return ad(x,mod-y);}
- il int mul(int x,int y){return (ll)x*y%mod;}
- struct tr{
- int a[][];
- tr(){memset(a,,sizeof a);}
- void init(){
- a[][]=a[][]=a[][]=;
- }
- tr friend operator *(const tr &a,const tr &b){
- tr c;
- for(reg i=;i<;++i){
- for(reg k=;k<;++k){
- for(reg j=;j<;++j){
- c.a[i][j]=ad(c.a[i][j],mul(a.a[i][k],b.a[k][j]));
- }
- }
- }return c;
- }
- tr friend operator +(const tr &a,const tr &b){
- tr c;
- for(reg i=;i<;++i){
- for(reg j=;j<;++j){
- c.a[i][j]=ad(a.a[i][j],b.a[i][j]);
- }
- }
- return c;
- }
- tr friend operator -(const tr &a,const tr &b){
- tr c;
- for(reg i=;i<;++i){
- for(reg j=;j<;++j){
- c.a[i][j]=ad(a.a[i][j],mod-b.a[i][j]);
- }
- }
- return c;
- }
- tr friend operator *(const tr &a,const int &v){
- tr c;
- for(reg i=;i<;++i){
- for(reg j=;j<;++j){
- c.a[i][j]=mul(a.a[i][j],v);
- }
- }
- return c;
- }
- void out(){
- for(reg i=;i<;++i){
- for(reg j=;j<;++j){
- cout<<a[i][j]<<" ";
- }cout<<endl;
- }
- }
- }S,A,I,B,c[N],ans[N];
- tr qm(tr x,int y){
- tr ret;ret.init();
- while(y){
- if(y&) ret=ret*x;
- x=x*x;
- y>>=;
- }
- return ret;
- }
- namespace Polynomial{
- struct Poly{
- vector<int>f;
- Poly(){f.clear();}
- il int &operator[](const int &x){return f[x];}
- il const int &operator[](const int &x) const {return f[x];}
- il void resize(const int &n){f.resize(n);}
- il int size() const {return f.size();}
- il void cpy(Poly &b){f.resize(b.size());for(reg i=;i<(int)f.size();++i)f[i]=b[i];}
- il void rev(){reverse(f.begin(),f.end());}
- il void clear(){f.clear();}
- il void read(const int &n){f.resize(n);for(reg i=;i<n;++i)rd(f[i]);}
- il void out() const {for(reg i=;i<(int)f.size();++i)ot(f[i]);putchar('\n');}
- }R;
- il int init(const int &n){int m;for(m=;m<n;m<<=);return m;}
- template<class T>il void rev(T &f){
- int lp=f.size();
- if(R.size()!=f.size()) {
- R.resize(f.size());
- for(reg i=;i<lp;++i){
- R[i]=(R[i>>]>>)|((i&)?lp>>:);
- }
- }
- for(reg i=;i<lp;++i){
- if(i<R[i]) swap(f[i],f[R[i]]);
- }
- }
- }
- using namespace Polynomial;
- //--------------------------------------------------------------------------------------------------------------------//
- il void operator +=(Poly &f,const Poly &g){for(reg i=;i<f.size();++i) f[i]=ad(f[i],g[i]);}
- il void operator +=(Poly &f,const int &c){f[]=ad(f[],c);}
- il Poly operator +(Poly f,const Poly &g){for(reg i=;i<f.size();++i) f[i]=ad(f[i],g[i]);return f;}
- il Poly operator +(Poly f,const int &c){f[]=ad(f[],c);return f;}
- il void operator -=(Poly &f,const Poly &g){for(reg i=;i<f.size();++i) f[i]=sub(f[i],g[i]);}
- il void operator -=(Poly &f,const int &c){f[]=sub(f[],c);}
- il Poly operator -(Poly f,const Poly &g){for(reg i=;i<f.size();++i) f[i]=sub(f[i],g[i]);return f;}
- il Poly operator -(Poly f,const int &c){f[]=sub(f[],c);return f;}
- il Poly operator -(Poly f){for(reg i=;i<f.size();++i) f[i]=mod-f[i];return f;}
- //--------------------------------------------------------------------------------------------------------------------//
- namespace FastFourierTransform{
- struct cplx{
- double x,y;
- cplx(){x=0.0;y=0.0;}
- cplx(double xx,double yy){x=xx;y=yy;}
- cplx friend operator !(cplx a){return cplx(a.x,-a.y);}
- cplx friend operator +(cplx a,cplx b){return cplx(a.x+b.x,a.y+b.y);}
- cplx friend operator -(cplx a,cplx b){return cplx(a.x-b.x,a.y-b.y);}
- cplx friend operator *(cplx a,cplx b){return cplx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
- };
- struct Cps{
- vector<cplx>f;
- Cps(){f.clear();}
- il cplx &operator[](const int &x){return f[x];}
- il const cplx &operator[](const int &x) const {return f[x];}
- il void resize(const int &n){f.resize(n);}
- il int size() const {return f.size();}
- il void cpy(Cps &b){f.resize(b.size());for(reg i=;i<(int)f.size();++i)f[i]=b[i];}
- il void rev(){reverse(f.begin(),f.end());}
- il void clear(){f.clear();}
- il void out(){
- for(reg i=;i<(int)f.size();++i){
- cout<<"("<<f[i].x<<","<<f[i].y<<") ";
- }cout<<endl;
- }
- }W;
- il void FFT(Cps &f,int c){
- int n=f.size();rev(f);
- for(reg p=;p<=n;p<<=){
- int len=p/;
- for(reg l=;l<n;l+=p){
- for(reg k=l;k<l+len;++k){
- cplx tmp=f[k+len]*(c>?W[n/p*(k-l)]:!W[n/p*(k-l)]);
- f[k+len]=f[k]-tmp;
- f[k]=f[k]+tmp;
- }
- }
- }
- if(c==-){
- for(reg i=;i<n;++i){
- f[i].x/=n;f[i].y/=n;
- }
- }
- }
- il void prework(int n){
- if(W.size()!=n){
- W.resize(n);
- for(reg i=;i<n;++i){
- W[i]=cplx(cos(*Pi/n*i),sin(*Pi/n*i));
- }
- }
- }
- il Poly MTT(const Poly &F,const Poly &G,const int &P){
- int n=F.size(),m=G.size();
- Cps a,b,c,d;
- int len=init(n+m-);
- a.resize(len);b.resize(len);
- c.resize(len);d.resize(len);
- for(reg i=;i<n;++i){
- a[i].x=F[i]>>;a[i].y=F[i]&;
- }
- for(reg i=;i<m;++i){
- b[i].x=G[i]>>;b[i].y=G[i]&;
- }
- prework(len);
- FFT(a,);FFT(b,);
- cplx ka,kb,ba,bb;
- cplx aaa=cplx(0.5,),bbb=cplx(,-0.5),o=cplx(,);
- for(reg i=;i<len;++i){
- int j=(len-i)%len;
- ka=(a[i]+!a[j])*aaa;ba=(a[i]-!a[j])*bbb;
- kb=(b[i]+!b[j])*aaa;bb=(b[i]-!b[j])*bbb;
- c[i]=ka*kb+ba*kb*o;
- d[i]=bb*ka+bb*ba*o;
- }
- FFT(c,-);FFT(d,-);
- Poly ret;
- ret.resize(n+m-);
- for(reg i=;i<n+m-;++i){
- ll A=(ll)(c[i].x+0.5)%P,B=(ll)(c[i].y+0.5)%P;
- ll C=(ll)(d[i].x+0.5)%P,D=(ll)(d[i].y+0.5)%P;
- ret[i]=((((A<<)%P)+((B+C)<<)%P)%P+D)%P;
- }
- return ret;
- }
- il void operator *=(Poly &f,Poly g){
- f=MTT(f,g,mod);
- }
- il void operator *=(Poly &f,const int &c){for(reg i=;i<f.size();++i) f[i]=mul(f[i],c);}
- il Poly operator *(Poly f,const Poly &g){f*=g;return f;}
- il Poly operator *(Poly f,const int &c){for(reg i=;i<f.size();++i) f[i]=mul(f[i],c);return f;}
- il Poly Inv(const Poly &f,int n){
- if(n==){
- Poly g;g.resize();g[]=qm(f[],mod-);return g;
- }
- Poly h=Inv(f,(n+)>>);
- Poly tmp=h,t;
- t.resize(n);
- for(reg i=;i<n;++i) t[i]=f[i];
- tmp=tmp*tmp*t;
- h.resize(tmp.size());
- Poly g=h*-tmp;
- g.resize(n);
- return g;
- }
- }
- using namespace FastFourierTransform;
- int pri[N],cnt;
- void fin(){
- int lp=mod-;
- for(reg i=;(ll)i*i<=lp;++i){
- if(lp%i==){
- ++cnt;
- pri[cnt]=i;
- while(lp%i==) lp/=i;
- }
- }
- if(lp) pri[++cnt]=lp;
- // cout<<" cnt "<<cnt<<endl;
- // prt(pri,1,cnt);
- G=;
- lp=mod-;
- for(;;++G){
- bool fl=true;
- for(reg j=;j<=cnt;++j){
- if(qm(G,lp/pri[j])==) fl=false;
- }
- if(fl) break;
- }
- }
- int main(){
- int n;
- rd(n);rd(K);rd(L);rd(X);rd(Y);rd(mod);
- --X;--Y;
- fin();
- GI=qm(G,mod-);
- // cout<<" GG "<<G<<" GI "<<GI<<endl;
- for(reg i=;i<n;++i){
- for(reg j=;j<n;++j){
- rd(A.a[i][j]);
- }
- }
- I.init();
- S.a[][X]=;
- int now=;
- w=qm(G,(mod-)/K);
- int T=qm(w,mod-);
- for(reg i=;i<K;++i){
- c[i]=qm((A*now)+I,L)*qm(w,(ll)i*(i-)/);
- now=mul(now,w);
- // cout<<" i "<<i<<endl;
- // c[i].out();
- // cout<<endl;
- }
- Poly g;
- g.resize(*K-);
- for(reg i=;i<*K-;++i){
- g[i]=qm(T,(ll)i*(i-)/);
- }
- g.rev();
- Poly f;
- f.resize(*K-);
- for(reg i=;i<;++i){
- int j=Y;
- f.clear();
- f.resize(*K-);
- for(reg k=;k<K;++k){
- f[k]=c[k].a[i][j];
- }
- // f.out();
- // g.out();
- // cout<<endl;
- f*=g;
- // cout<<" ff "<<endl;
- // f.out();
- // cout<<" edn "<<endl;
- for(reg k=;k<f.size();++k){
- ans[k].a[i][j]=f[k];
- }
- // for(reg k=0;k<K;++k){
- // // cout<<" ans[k] "<<k<<endl;
- // // ans[k].out();
- // }
- }
- for(reg t=;t<K;++t){
- tr now=ans[*K--t];
- // cout<<" tt "<<t<<endl;now.out();
- now=now*qm(w,(ll)t*(t-)/)*qm(K,mod-);
- tr out=S*now;
- // ot(out.a[0][Y]);
- printf("%d\n",out.a[][Y]);
- }
- return ;
- }
- }
- signed main(){
- Miracle::main();
- return ;
- }
- /*
- Author: *Miracle*
- Date: 2019/4/8 18:57:00
- */
[HNOI2019]白兔之舞的更多相关文章
- HNOI2019 白兔之舞 dance
HNOI2019 白兔之舞 dance 显然\(n=3\)就是\(n=1\)的扩展版本,先来看看\(n=1\)怎么做. 令\(W=w[1][1]\),显然答案是:\(ans_t=\sum_{i\mod ...
- luogu P5293 [HNOI2019]白兔之舞
传送门 关于这题答案,因为在所有行,往后跳到任意一行的\(w_{i,j}\)都是一样的,所以可以算出跳\(x\)步的答案然后乘上\(\binom{l}{x}\),也就是枚举跳到了哪些行 如果记跳x步的 ...
- 【Luogu5293】[HNOI2019] 白兔之舞
题目链接 题目描述 略 Sol 考场上暴力 \(O(L)\) 50分真良心. 简单的推一下式子,对于一个 t 来说,答案就是: \[\sum_{i=0}^{L} [k|(i-t)] {L\choose ...
- [HNOI2019]白兔之舞(矩阵快速幂+单位根反演)
非常抱歉,这篇文章鸽了.真的没时间写了. #include<bits/stdc++.h> using namespace std; typedef long long ll; #defin ...
- Loj 3058. 「HNOI2019」白兔之舞
Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...
- 「loj3058」「hnoi2019」白兔之舞
题意 有一个\((L+1)*n\) 的网格图,初始时白兔在\((0,X)\) , 每次可以向横坐标递增,纵坐标随意的位置移动,两个位置之间的路径条数只取决于纵坐标,用\(w(i,j)\) 表示,如果要 ...
- LOJ3058. 「HNOI2019」白兔之舞 [DP,MTT]
LOJ 前置知识:任意长度NTT 普通NTT只能做\(2^k\)的循环卷积,尝试扩展成长度为\(n\)的循环卷积,保证模意义下\(\omega_n\)存在. 不管怎样还是要算点值.推式子: \[ \b ...
- LOJ 3058 「HNOI2019」白兔之舞——单位根反演+MTT
题目:https://loj.ac/problem/3058 先考虑 n=1 怎么做.令 a 表示输入的 w[1][1] . \( ans_t = \sum\limits_{i=0}^{L}C_{L} ...
- 「HNOI 2019」白兔之舞
一道清真的数论题 LOJ #3058 Luogu P5293 题解 考虑$ n=1$的时候怎么做 设$ s$为转移的方案数 设答案多项式为$\sum\limits_{i=0}^L (sx)^i\bin ...
随机推荐
- 【JZOJ4359】【GDKOI2016】魔卡少女
题目描述 君君是中山大学的四年级学生.有一天在家不小心开启了放置在爸爸书房中的一本古书.于是,君君把放在书中最上面的一张牌拿出来观摩了一下,突然掀起一阵大风把书中的其她所有牌吹散到各地.这时一只看上去 ...
- jq向元素附加数据
--------data() 方法向被选元素附加数据,或者从被选元素获取数据.--------- --------removeData() 方法删除之前通过 data() 方法设置的数据.------ ...
- 2019-11-1-asp-dotnet-core-简单开发P2P中央服务器
title author date CreateTime categories asp dotnet core 简单开发P2P中央服务器 lindexi 2019-11-01 19:40:33 +08 ...
- OpenJudge_1936:All in All
描述 You have devised a new encryption technique which encodes a message by inserting between its char ...
- HTML5入门指南
1.HTML5到底是什么? HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定.目标是取代1999年所制定的HTML 4.01和XHTML 1.0标准,以期能在互联 ...
- 块级元素及内联元素对margin、padding的态度
1.块级元素 margin:跟标准一样,设置该块级元素边框与同级兄弟元素或者父元素的距离,俗称外边距. padding:先延伸边框(也就是优先改变元素尺寸而不动元素中内容的位置),当边框碰到父元素的边 ...
- poj 2342 hdu 1520【树形dp】
poj 2342 给出每个顶点的happy值,还有若干组两个顶点L,K关系,表示K是L的上司.求当K.L不同时出现时获得的happy值的最大和. 设dp[u][0]表示不选u结点时获得的最大值,dp[ ...
- ros自定义消息
ros自定义消息可以根据自身项目需求定义和封装想要的数据类型和数据结构.具体可以参考维基百科关于ros自定义消息部分 这里我只是记录自定义消息的要点部分: 1.首先要在工作空间下功能包中创建一个msg ...
- Android GDI 图形渲染
发布于2011-07-26 导读:对于Android开发者来说,成系列的技术文章对他们的技术成长帮助最大.如下是我们向您强烈推荐的主题为Android开发的第一个系列文章. <Andro ...
- 从零学React Native之01创建第一个程序
本篇首发于简书 欢迎关注 上一篇文章是时候了解React Native了介绍了React Native.大家应该对React Native有个初步的认识. 接下来我们就可以初始化一个React Nat ...