zoukankan      html  css  js  c++  java
  • 矩阵快速幂 专题

    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
    ",a)
    #define ptlld(a) printf("%I64d
    ",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?'
    ':' ');
            }
        }
        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
    ",a)
    #define ptlld(a) printf("%I64d
    ",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
    不为失败找借口,只为成功找方法
  • 相关阅读:
    static,匿名对象
    构造方法
    面向对象
    数组拷贝,可变参数,foreach
    毕业设计 之 七 参考文献综述
    毕业设计 之 六 网站搭建学习笔记
    毕业设计 之 五 PHP语法学习笔记
    毕业设计 之 四 英文资料翻译
    毕业设计 之 三 mooodle及bigbluebutton使用笔记(未完成)
    毕业设计 之 二 PHP集成环境(Dreamweaver)使用
  • 原文地址:https://www.cnblogs.com/youmi/p/4885224.html
Copyright © 2011-2022 走看看