这类题目的难点在于,数据量大,需要用到高精度,也就是快速幂
https://codeforces.com/group/vFwRVj9WjO/contest/328371/problem/H
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define M 1000000007 using namespace std; typedef long long LL; struct Matrix { LL num[64][64]; }; LL n; int m,K; LL G[64][64]; Matrix mul(Matrix p,Matrix q) { Matrix ret; for(int i=0; i<m; i++) for(int j=0; j<m; j++) { ret.num[i][j] = 0; for(int k=0; k<m; k++) { ret.num[i][j] += p.num[i][k] * q.num[k][j]; ret.num[i][j] %= M; } } return ret; } Matrix f() { Matrix ret,p; memset(ret.num,0,sizeof(ret.num)); for(int i=0; i<m; i++) ret.num[i][i] = 1; for(int i=0; i<m; i++) for(int j=0; j<m; j++) p.num[i][j] = G[i][j]; n--; while(n) { if(n&1) ret = mul(ret,p); p = mul(p,p); n >>= 1; } return ret; } int main() { while(scanf("%I64d%d%d",&n,&m,&K) == 3) { int i,j; for(i=0; i<m; i++) for(j=0; j<m; j++) G[i][j] = 1; // 最开始,所有的i和j都是可以连在一起的 while(K--) { char c1,c2; int x,y; scanf("%c %c",&c1,&c2); x = c1>='a'&&c1<='z'?c1-'a':c1-'A'+26; y = c2>='a'&&c2<='z'?c2-'a':c2-'A'+26; G[x][y] = 0; // 这两个不可以连在一起 } Matrix ansM = f(); // for(i=0; i<m; i++) LL ans = 0; for(i=0; i<m; i++) { for(j=0; j<m; j++) { ans += ansM.num[i][j]; ans %= M; } } printf("%I64d\n",ans); } return 0; }
第二个模板
#include<bits/stdc++.h> const int INF = 0x3f3f3f3f; using namespace std; typedef long long ll; typedef double ld; int i,j,k; using namespace std; #define N 100 #define MOD 1000000007 long long n; int m; int k; int indice(char x) { if(x>='a' && x<='z') return x-'a'; else return x-'A'+26; }//预处理字符转数字 long long c[N][N]; void cheng(long long a[][N],long long b[][N]) { memset(c,0,sizeof(c)); for(int i=0; i<m; i++) for(int j=0; j<m; j++) for(int k=0; k<m; k++) c[i][j]=(c[i][j]+a[i][k]*b[k][j])%MOD; memcpy(a,c,sizeof(c)); } long long res[N][N]; long long odd[N][N]; void pow(long long p) { memset(odd,0,sizeof(odd)); for(int i=0; i<m; i++) odd[i][i]=1; if(p==0) { memcpy(res,odd,sizeof(odd)); return; } while(p>1) { if(p&1) cheng(odd,res); cheng(res,res); p/=2; } cheng(res,odd); } string s; int main() { cin>>n>>m>>k; for(int i=0; i<m; i++) for(int j=0; j<m; j++) res[i][j]=1; for(int i=0; i<k; i++) { cin>>s; res[indice(s[0])][indice(s[1])]=0; } n--; pow(n); long long cont=0; for(int i=0; i<m; i++) for(int j=0; j<m; j++) cont=(cont+res[i][j])%MOD; cout<<cont<<endl; return 0; }