1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include<bits/stdc++.h> using namespace std; const int maxm=505; const int maxn=55; const int P=5557; int N,M,T,Ans,L[maxm],R[maxm],X[maxm]; struct graph{ int n,ans[maxn][maxn]; graph(){clear();} void setNodeNumber(int n_){n=n_;} void addEdge(int l,int r){ans[l][r]=(ans[l][r]+1)%P;} void init(int n_){setNodeNumber(n_);for(int i=1;i<=n;i++)ans[i][i]=1;} void clear(){n=0;memset(ans,0x00,sizeof ans);} void operator*=(const graph B){ graph C;C.n=n; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C.ans[i][j]=(C.ans[i][j]+ans[i][k]*B.ans[k][j]%P)%P; *this=C; } void operator^=(const int B){ graph w=*this,ret;ret.init(n); for(int k=B;k;k>>=1){if(k&1) ret*=w;w*=w;} *this=ret; } int getAns(int s,int t){return ans[s][t];} }Map; int read(){ int f=1,ret=0;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-f; ch=getchar();} while( isdigit(ch)) ret=(ret<<3)+(ret<<1)+(ch&15),ch=getchar(); return f*ret; } int countTrueBinary(int x){ int ret=0; for(int k=0;k<0x20;k++) if(x&1<<k) ret++; return ret; } int main(){ N=read(),M=read(); for(int i=1;i<=M;i++){ L[i]=read(),R[i]=read();string s;cin>>s; for(int j=0;j<s.size();j++) switch(s[j]){ case'B':X[i]|=0x08;break; case'J':X[i]|=0x04;break; case'M':X[i]|=0x02;break; case'P':X[i]|=0x01;break; } } T=read(); for(int k=0;k<0x10;k++){ Map.clear(); Map.setNodeNumber(N<<1|1); Map.addEdge( 1,N<<1|1); Map.addEdge(N<<1|1,N<<1|1); for(int i=1;i<=N;i++) Map.addEdge(i,i+N); for(int i=1;i<=M;i++) Map.addEdge(L[i],R[i]); for(int i=1;i<=M;i++) if((X[i]&k)==X[i]) Map.addEdge(L[i]+N,R[i]); Map^=T+1; if(countTrueBinary(k)&1) Ans=((Ans-Map.getAns(1,N<<1|1))%P+P)%P; else Ans= (Ans+Map.getAns(1,N<<1|1))%P ; } printf("%d\n",Ans); return 0; }
|