快速幂(普通快速幂、矩阵快速幂)

来源:互联网 发布:中央人民大学网络教育 编辑:程序博客网 时间:2024/06/05 17:13

题目地址:HDU 2604 Queuing

题意: 
n个人排队,f表示女,m表示男,包含子串‘fmf’和‘fff’的序列为O队列,否则为E队列,有多少个序列为E队列。

分析: 
矩阵快速幂入门题。 
下面引用巨巨解释:

用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1); 
如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf, fmf, mff, fff,其中fff和fmf不满足题意所以我们不考虑,但是如果是 
mmf的话那么前n-3可以找满足条件的即:f(n-3);如果是mff的话,再往前考虑一位的话只有mmff满足条件即:f(n-4) 
所以f(n)=f(n-1)+f(n-3)+f(n-4),递推会跪,可用矩阵快速幂 
构造一个矩阵: 
pic

矩阵快速幂和普通的快速幂原理是一样的,如果不懂可以先去补补快速幂。

int power(int x,int y){int ans=1;while(y){if(y&1) ans=(ans*x)%mod;y>>=1;x=(x*x)%mod;}return ans;}


#include<bits/stdc++.h>using namespace std;const int inf=0x3f3f3f3f;typedef long long ll;int l,mod;struct node{    ll v[4][4];    node(){memset(v,0,sizeof v);}    void init(ll a){for(int i=0;i<4;i++) v[i][i]=a;}};node mult(node a,node b){    node c;    for(int i=0;i<4;i++)    for(int j=0;j<4;j++)    {        c.v[i][j]=0;        for(int k=0;k<4;k++)            c.v[i][j]+=(a.v[i][k]*b.v[k][j])%mod,            c.v[i][j]%=mod;    }    return c;}node power(node n,ll p){    node ans;    ans.init(1);    while(p)    {        if(p&1) ans=mult(ans,n);        p>>=1;        n=mult(n,n);    }    return ans;}int main(){    node a,b,c;    a.v[0][0]=9;    a.v[1][0]=6;    a.v[2][0]=4;    a.v[3][0]=2;    b.v[0][0]=b.v[0][2]=b.v[0][3]=b.v[1][0]=b.v[2][1]=b.v[3][2]=1;    while(~scanf("%d%d",&l,&mod))    {        if(l==0) puts("0");        else if(l<=4) printf("%lld\n",a.v[4-l][0]%mod);        else c=power(b,l-4),c=mult(c,a),printf("%lld\n",c.v[0][0]%mod);    }    return 0;}

http://poj.org/problem?id=3070

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int mod=10000;struct node{long long f[5][5];void init(){memset(f,0,sizeof f);}}a,b;long long n;node operator *(node a,node b){node c;c.init();for(int i=1;i<=2;i++)for(int j=1;j<=2;j++)for(int k=1;k<=2;k++)c.f[i][j]=(c.f[i][j]+a.f[i][k]*b.f[k][j])%mod;return c;}void power(long long y){while(y){if(y&1) a=a*b;y>>=1;b=b*b;}}int main(){while(~scanf("%lld",&n),n!=-1){a.init();b.init();a.f[1][2]=1;b.f[1][2]=b.f[2][1]=b.f[2][2]=1;power(n);printf("%lld\n",a.f[1][1]);}return 0;}

传送门:https://vijos.org/p/1603


#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct node{    long long f[55][55];    void clear(){memset(f,0,sizeof f);}    void init(){for(int i=0;i<55;i++) f[i][i]=1;}    };int n,s,f,m,mod;node operator *(node x,node y){    node res;    res.clear();    for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)    for(int k=1;k<=n;k++)        res.f[i][j]=(res.f[i][j]+x.f[i][k]*y.f[k][j])%mod;    return res;}node power(node x,int y){    node res;    res.init();    while(y)    {        if(y&1) res=res*x;        y>>=1;        x=x*x;    }    return res;}int main(){    int t,tt=0,x,y;    node a;    cin>>n;    for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)        cin>>a.f[i][j];        cin>>m>>s>>f>>mod;    a=power(a,m);    cout<<a.f[s][f]<<endl;        return 0;}

https://acm.bnu.edu.cn/v3/problem_show.php?pid=52322

//#include<bits/stdc++.h> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N=7; typedef long long ll; struct node { ll f[N][N]; node() {memset(f,0,sizeof f);} void init() { f[0][1]=f[1][0]=f[1][1]=1; } }; ll p,n,m,h=2; node operator *(node x,node y) { node res; for(int i=0;i<h;i++) for(int j=0;j<h;j++) for(int k=0;k<h;k++) res.f[i][j]=(res.f[i][j]+x.f[i][k]*y.f[k][j])%p; return res; } ll power(node x,ll y) { node res; res.f[0][1]=1; while(y) { if(y&1) res=res*x; y>>=1; x=x*x; }return res.f[0][0]; } int main() { int t; node x; x.init(); scanf("%d",&t); while(t--) { scanf("%lld",&n); p=13440348*2; ll b=power(x,n)+p; p=20160519; printf("%lld\n",power(x,b)); } return 0; } 



0 0
原创粉丝点击