poj 3233 Matrix Power Series http://poj.org/problem?id=3233
/************************************************************** Problem:poj 3233 User: youmi Language: C++ Result: Accepted Time:1735MS Memory:3880K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\n",a) #define ptlld(a) printf("%I64d\n",a) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define rep_1(i,n) for(int i=n;i>=1;i--) #define rep_0(i,n) for(int i=n-1;i>=0;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; int n,tot,mod; const int maxn=50; typedef struct T { int mat[maxn][maxn]; }matrix; matrix org,ans,unit; matrix operator+(matrix a,matrix b) { matrix c; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%mod; return c; } matrix operator*(matrix a,matrix b) { matrix c; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { c.mat[i][j]=0; for(int k=1;k<=n;k++) c.mat[i][j]=(c.mat[i][j]+(a.mat[i][k]*b.mat[k][j])%mod)%mod; } return c; } matrix q_pow(int k) { matrix res=unit,p=org; while(k) { if(k&1) res=res*p; k>>=1; p=p*p; } return res; } matrix solve(int k) { if(k==1) return org; int half=k>>1; matrix temp=solve(half); matrix t; if(k&1) { t=q_pow(half+1); temp=t+temp+temp*t; } else { t=q_pow(half); temp=temp+temp*t; } return temp; } void init() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { org.mat[i][j]%=mod; unit.mat[i][j]=(i==j); } } } int main() { //freopen("in.txt","r",stdin); while(~sc3(n,tot,mod)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&org.mat[i][j]); init(); ans=solve(tot); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) printf("%d%c",ans.mat[i][j],j==n?'\n':' '); } } return 0; }
题意:题目大概说用k个不同的字母,有多少种方法构造出两个长度n最长公共子串长度为m的字符串。
思路:
f[0][0]=1;
f[i][j]表示构造好前i个,最后j个相同的方案数
f[i][j]=f[i-1][j-1]*k 【最后一位有k种方案相同】
f[i][0]=sigma(f[i-1][j])*k*(k-1) j=0~m 【倒数第二位相同最后一位不同有k*(k-1)种方案】
只维护f[i][0~m],可以求出value<=m的答案
因为n很大而m很小,所以我们就可以构造矩阵转移
快速幂出来的第一排就是所要的value<=m的答案
然后再减去value<=m-1的答案,就是所求答案了
/************************************************************** Problem:hdu 5863 cjj's string game User: youmi Language: C++ Result: Accepted Time:46MS Memory:1576K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <set> #include <sstream> #include <cmath> #include <queue> #include <deque> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scs(a) scanf("%s",a) #define sclld(a) scanf("%I64d",&a) #define pt(a) printf("%d\n",a) #define ptlld(a) printf("%I64d\n",a) #define rep(i,from,to) for(int i=from;i<=to;i++) #define irep(i,to,from) for(int i=to;i>=from;i--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define lson (step<<1) #define rson (lson+1) #define eps 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl const double pi=4*atan(1.0); using namespace std; typedef long long ll; template <class T> inline void read(T &n) { char c; int flag = 1; for (c = getchar(); !(c >= '0' && c <= '9' || c == '-'); c = getchar()); if (c == '-') flag = -1, n = 0; else n = c - '0'; for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0'; n *= flag; } ll Pow(ll base, ll n, ll mo) { if (n == 0) return 1; if (n == 1) return base % mo; ll tmp = Pow(base, n >> 1, mo); tmp = (ll)tmp * tmp % mo; if (n & 1) tmp = (ll)tmp * base % mo; return tmp; } //*************************** int n,m,kind; const int maxn=11; const ll mod=1000000007; struct matrix { ll mat[maxn][maxn]; int tt;// from 0 to tt ;tt+1 void init() { rep(i,0,tt) rep(j,0,tt) mat[i][j]=0; rep(j,0,tt) { if(j==0) { rep(k,0,tt) mat[j][k]=kind*(kind-1); } else mat[j][j-1]=kind; } } matrix operator*(const matrix & rhs)const { matrix ans; rep(i,0,tt) rep(j,0,tt) ans.mat[i][j]=0; ans.tt=tt; rep(i,0,tt) rep(j,0,tt) rep(k,0,tt) ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*rhs.mat[k][j])%mod; return ans; } matrix operator^(ll k)const { matrix rhs=*this; matrix res; rep(i,0,tt) rep(j,0,tt) res.mat[i][j]=(i==j); res.tt=tt; while(k) { if(k&1) res=res*rhs; rhs=rhs*rhs; k>>=1; } return res; } }x; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int T_T; scanf("%d",&T_T); for(int kase=1;kase<=T_T;kase++) { sc3(n,m,kind); x.tt=m; x.init(); x=x^n; ll ans=0; rep(j,0,m) ans=(ans+x.mat[j][0]+mod)%mod; x.tt=m-1; x.init(); x=x^n; rep(j,0,m-1) ans=(ans+mod-x.mat[j][0])%mod; ptlld(ans); } }
不为失败找借口,只为成功找方法