矩阵快速幂。poj3070 3233 3735 3150

来源:互联网 发布:逆袭网络剧百度云网盘 编辑:程序博客网 时间:2024/06/09 16:39
poj 3070;
这是弱的第一道矩阵快速幂,然后试试手,总之还是裸模板。但还是蛮难的
#include <iostream>#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;typedef long long ll;const int mod=10000;ll n;struct Matrix{    ll ma[2][2];    Matrix()    {        for(int i=0;i<2;i++)         for(int j=0;j<2;j++)            ma[i][j]=0;    }};Matrix mult(Matrix a, Matrix b){    Matrix c;    for(int i=0;i<2;i++)    {      for(int j=0;j<2;j++)      {          for(int k=0;k<2;k++)          {              c.ma[i][j]=(c.ma[i][j]+a.ma[i][k]*b.ma[k][j]%mod)%mod;          }      }    }    return c;}Matrix pow(Matrix a,ll b){    Matrix temp;    for(int i=0;i<2;i++) temp.ma[i][i]=1;    while(b)    {        if(b&1) temp=mult(temp,a);        a=mult(a,a);        b>>=1;    }    return temp;}int main(){    while(scanf("%I64d",&n)!=EOF)    {        if(n==-1) break;        else if(n==0) {printf("0\n"); continue;}        Matrix a,b;        a.ma[0][0]=1;        a.ma[0][1]=1;        a.ma[1][0]=1;        b=pow(a,n);        printf("%I64d\n",b.ma[0][1]%mod);    }    return 0;}

poj  3725.
将每只猫的花生数放在一个1*n的矩阵中,考虑用k次操作构造成一个n*n矩阵A,因为三种操作中存在某种猫的花生数加一的操作,所以要把矩阵扩展一位放1,即[1,cnt1,cnt2,…,cntn],初始化矩阵A为单位矩阵,对于操作1,要把A[0][x]++;对于操作2,要令A[i][x]=0;对于操作3,要swap(A[i][x],A[i][y]),构造出A矩阵之后用矩阵快速幂求出A^m后第一行元素即为操作后每只猫的花生数. 但是弱还是不太会。看了题解,感觉这类题还是蛮神奇的。
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;typedef long long ll;ll n,m,k;struct Matrix{    ll ma[120][120];    Matrix()    {        for(int i=0;i<120;i++)        {            for(int j=0;j<120;j++)            {                ma[i][j]=0;            }        }    }} ;Matrix mult(Matrix a, Matrix b){    Matrix c;    for(int i=0;i<=n;i++)// 行    {        for(int j=0;j<=n;j++)        {           if(b.ma[i][j])           {               for(int k=0;k<=n;k++)               {                   c.ma[i][k]=(c.ma[i][k]+a.ma[i][j]*b.ma[j][k]);               }           }        }    }    return c;}Matrix pow(Matrix a,ll b){   if(b==1) return a;   Matrix ans;   for(int  i=0;i<=n;i++) ans.ma[i][i]=1;   while(b)   {       if(b & 1) ans=mult(ans,a);       b>>=1;       a=mult(a,a);   }   return ans;}int main(){    while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF)    {        if(n==0&&m==0&&k==0) break;        Matrix x,y;        for(int i=0;i<=n;i++) x.ma[i][i]=1;        while(k--)        {            char s[5];            scanf("%s",s);            if(s[0]=='g')            {                int t;                scanf("%d",&t);                x.ma[0][t]++;            }            else if(s[0]=='e')            {                int  t;                scanf("%d",&t);                for(int i=0;i<=n;i++)                    x.ma[i][t]=0;            }            else            {                int p,q;                scanf("%d%d",&p,&q);                for(int i=0;i<=n;i++)                {                    swap(x.ma[i][p],x.ma[i][q]);                }            }        }        y=pow(x,m);        for(int i=1;i<n+1;i++)        {            printf("%I64d",y.ma[0][i]);            if(i==n) printf("\n");            else printf(" ");        }    }    return 0;}

poj 3233.很牛逼的一道题,就看了一眼题解。神马二分。。。弱完全没想到最后的方法。
a^1+a^2+a^3+a^4+a^5=(a^1+a^2+a^3+a^4)+a^5
(a^1+a^2+a^3+a^4)=(a^1+a^2+a^2(a^1+a^2))=(a^1+a^2)*(1+a^2)
(a^1+a^2)=a^1(1+a^1)

如果k为偶数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)

如果k为奇数,那么(A+A^2+....A^K) = (A+...+A^K/2)+A^K/2*(A+...+A^K/2)+A^k

讨论奇偶性
式子不会放大。。。
#include <iostream>#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;typedef long long ll;ll n,k,m;struct Matix{    ll ma[31][31];    Matix()    {        for(int i=0;i<31;i++)        {            for(int j=0;j<31;j++)            {                ma[i][j]=0;            }        }    }};Matix p,q,ans;Matix mult(Matix a,Matix b){    Matix c;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)           {               for(int k=0;k<n;k++)               {                   c.ma[i][j]=(c.ma[i][j]+a.ma[i][k]*b.ma[k][j])%m;               }           }    }    return c;}Matix sum(Matix a,Matix b){    Matix c;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            c.ma[i][j]=(a.ma[i][j]+b.ma[i][j])%m;        }    }    return c;}Matix pow(Matix a,ll b){    Matix ans;    for(int i=0;i<n;i++) ans.ma[i][i]=1;    while(b)    {        if(b&1) ans=mult(ans,a);        a=mult(a,a);        b>>=1;    }    return ans;}Matix solve(Matix m,ll k){    if(k==1) return m;    else if(k%2) return m=sum(solve(m,k-1),pow(m,k));    else return mult(solve(m,k/2),sum(p,pow(m,k/2)));}int main(){    scanf("%I64d%I64d%I64d",&n,&k,&m);    for(int i=0;i<n;i++) p.ma[i][i]=1;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            scanf("%I64d",&q.ma[i][j]);        }    }    ans=solve(q,k);    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            printf("%I64d",ans.ma[i][j]);            if(j==n-1) printf("\n");            else printf(" ");        }    }    return 0;}









0 0
原创粉丝点击