P2579 [ZJOI2005]沼澤鱷魚
阿新 • • 發佈:2018-12-20
話說鄰接矩陣居然還能快速冪的麼……
把原圖的鄰接矩陣\(G\)打出來,那麼\(G[u][v]\)表示一秒後\(u\)到\(v\)的方案數,\(G^2[u][v]\)表示\(2\)秒後的方案數……於是只要矩陣快速冪計算\(G^k\)即可
然而有食人魚,會導致某些點在某些時刻不能走。發現\(lcm(2,3,4)=12\),於是我們可以構造\(12\)個鄰接矩陣\(P_1,P_2,...,P_{12}\)分別表示某個點在這個時刻能不能走,這樣就可以防止不能走的情況
令\(Q=P_1P_2...P_{12}\),那麼\(Ans=Q^{n/k}P_1P_2...P_{n\%k}\)
ps:矩陣乘法沒有交換律!運算順序不能亂!
//minamoto #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) using namespace std; char buf[1<<21],*p1=buf,*p2=buf; inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} int read(){ R int res,f=1;R char ch; while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f; } const int N=55,P=10000; inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;} inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;} int n,m,s,t,k,q,u,v,T,w[5]; struct Matrix{ int a[N][N]; Matrix(){memset(a,0,sizeof(a));} inline int* operator [](R int x){return a[x];} Matrix operator *(Matrix b){ Matrix res; fp(i,1,n)fp(j,1,n)fp(k,1,n) res[i][j]=add(res[i][j],1ll*a[i][k]*b[k][j]%P); return res; } }ans,g[15]; Matrix ksm(Matrix x,R int y){ Matrix res;fp(i,1,n)res[i][i]=1; for(;y;y>>=1,x=x*x)if(y&1)res=res*x; return res; } int main(){ // freopen("testdata.in","r",stdin); n=read(),m=read(),s=read()+1,t=read()+1,k=read(); while(m--){ u=read()+1,v=read()+1; fp(j,1,12)g[j][u][v]=g[j][v][u]=1; }q=read(); while(q--){ T=read();fp(i,1,T)w[i]=read()+1; fp(i,1,n)fp(j,0,12) g[j][i][w[j%T+1]]=0; }fp(i,1,n)ans[i][i]=1; fp(i,1,12)ans=ans*g[i]; ans=ksm(ans,k/12);fp(i,1,k%12)ans=ans*g[i]; printf("%d\n",ans[s][t]);return 0; }