NOI 2013 矩阵游戏

http://uoj.ac/problem/124

矩阵乘法。

十进制快速幂。

刚开始还傻傻地写二进制快速幂,然后陈老师一语点醒梦中人......

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
 
using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define re(i,a,b)  for(i=a;i<=b;i++)
#define red(i,a,b) for(i=a;i>=b;i--)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline void clear(vector<int> *A,int a,int b){int i,j;A->clear();re(i,0,a)re(j,0,b)A[i].push_back(0);}

inline int gint()
  {
        int res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }
inline LL gll()
  {
      LL res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res;
    }

const LL Mod=1000000007;
const int maxlen=1000000;

char N[maxlen+1000],M[maxlen+100];
LL a,b,c,d;

struct Tmatrix
  {
      LL v[3][3];
      inline void clear(){mmst(v,0);}
      inline friend Tmatrix operator *(const Tmatrix &a,const Tmatrix &b)
        {
            Tmatrix c;
            c.v[1][1]=(a.v[1][1]*b.v[1][1]+a.v[1][2]*b.v[2][1])%Mod;
            c.v[1][2]=(a.v[1][1]*b.v[1][2]+a.v[1][2]*b.v[2][2])%Mod;
            c.v[2][1]=(a.v[2][1]*b.v[1][1]+a.v[2][2]*b.v[2][1])%Mod;
            c.v[2][2]=(a.v[2][1]*b.v[1][2]+a.v[2][2]*b.v[2][2])%Mod;
            return c;
        }
  };

inline void minus1(char *A)
  {
      int i,t;
      for(t=1;A[t]=='0';t++);
      re(i,1,t-1)A[i]='9';
      A[t]--;
  }

Tmatrix f1,f2,f1n,g;

Tmatrix A[maxlen+100];
inline Tmatrix power2(Tmatrix a,int k)
  {
      Tmatrix x,y=a;
        x.v[1][1]=1;x.v[1][2]=0;x.v[2][1]=0;x.v[2][2]=1;
        while(k!=0){if(k&1)x=x*y;y=y*y;k>>=1;}
        return x;
    }
inline Tmatrix power(Tmatrix a,char *K)
  {
      int i,l=strlen(K+1);
      A[1]=a;re(i,2,l)A[i]=power2(A[i-1],10);
        Tmatrix x;x.v[1][1]=1;x.v[1][2]=0;x.v[2][1]=0;x.v[2][2]=1;
        re(i,1,l)x=x*power2(A[i],K[i]-'0');
        return x;
    }

int main()
  {
      freopen("matrix.in","r",stdin);
        freopen("matrix.out","w",stdout);
        int i,l;
        SF("%s",N+1);
        l=strlen(N+1);re(i,1,l/2)swap(N[i],N[l-i+1]);
        SF("%s",M+1);
        l=strlen(M+1);re(i,1,l/2)swap(M[i],M[l-i+1]);
        a=gint();b=gint();c=gint();d=gint();
      f1.v[1][1]=a;f1.v[1][2]=b;f1.v[2][1]=0;f1.v[2][2]=1;
      f2.v[1][1]=c;f2.v[1][2]=d;f2.v[2][1]=0;f2.v[2][2]=1;
      minus1(M);
      minus1(N);
      f1n=power(f1,M);
      g=f2*f1n;
      g=power(g,N);
      g=f1n*g;
        cout<<(g.v[1][1]+g.v[1][2])%Mod<<endl;      
  }
View Code

 

posted @ 2015-07-29 19:18  maijing  阅读(244)  评论(0编辑  收藏  举报