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;
}

 

hdu 5863 cjj's string game

题意:题目大概说用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);
    }
}
View Code

 

posted on 2015-10-16 14:31  中子星  阅读(185)  评论(0编辑  收藏  举报