每次除2的快速幂超时了,如果用十进制快速幂的话,会快很多
校赛I题
#include<cstdio>
#include<iostream>
using namespace std;
string s, tmp;
const long long mod=1000000007;
class Matrix{
public:
int row;
int col;
long long ** element;
Matrix();
~Matrix();
Matrix(const int , const int);
Matrix(const Matrix &);
Matrix operator = (const Matrix &);
Matrix operator + (const Matrix &);
Matrix operator * (const Matrix &);
void setMatrix();
void print()
{
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
cout<<element[i][j]<<" ";
cout<<endl;
}
}
Matrix quickpow(int n)
{
Matrix result(row, col);
Matrix a=*this;
for(int i=0; i<row; i++)
result.element[i][i]=1;
while(n)
{
if(n%2==1)
result=a*result;
n=n>>1;
a=a*a;
}
return result;
}
Matrix quickpow1()
{
Matrix result(row, col);
for(int i=0; i<row; i++)
result.element[i][i]=1;
Matrix t=*this;
Matrix tmp=t;
for(int i=s.size()-1; i>=0; i--)
{
tmp=t.quickpow(s[i]-'0');
result=result*tmp;
t=t.quickpow(10);
}
return result;
}
};
Matrix::Matrix()
{
row=col=0;
element=NULL;
}
Matrix::~Matrix()
{
for(int i=0; i<row; i++)
delete []element[i];
delete []element;
}
Matrix::Matrix(const int m_row, const int m_col)
{
row = m_row;
col = m_col;
element = new long long *[row];
for(int i=0; i<row; i++)
element[i] = new long long[col];
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
element[i][j]=0;
}
Matrix::Matrix(const Matrix & temp)
{
row = temp.row;
col = temp.col;
element = new long long *[row];
for(int i=0; i<row; i++)
element[i] = new long long[col];
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
element[i][j]=temp.element[i][j];
}
Matrix Matrix::operator =(const Matrix & right)
{
for(int i=0; i<row; i++)
delete []element[i];
delete []element;
row = right.row;
col = right.col;
element = new long long *[row];
for(int i=0; i<row; i++)
element[i] = new long long[col];
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
element[i][j]=right.element[i][j];
return *this;
}
Matrix Matrix::operator + (const Matrix & right)
{
Matrix result(row, col);
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
result.element[i][j] = (element[i][j] + right.element[i][j])%mod;
return result;
}
Matrix Matrix::operator *(const Matrix & right)
{
Matrix result(row, right.col);
for(int i=0; i<row; i++)
for(int j=0; j<right.col; j++)
{
result.element[i][j]=0;
for(int k=0; k<col; k++)
{
result.element[i][j]+=(element[i][k]*right.element[k][j])%mod;
result.element[i][j]%=mod;
}
}
return result;
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("11.txt", "w", stdout);
Matrix tmp(3, 3);
tmp.element[0][0]=2;tmp.element[0][1]=1;tmp.element[0][2]=3;
tmp.element[1][0]=1;tmp.element[2][1]=1;
while(cin>>s)
{
if(s.size()==1)
{
if(s[0]=='1'){
cout<<1<<endl;continue;
}
else if(s[0]=='2')
{
cout<<2<<endl; continue;
}
else if(s[0]=='0')
{
cout<<0<<endl; continue;
}
else if(s[0]=='3')
{
cout<<5<<endl; continue;
}
else s[0]-=3;
}
else
{
int k = s.size()-1;
if(s[k]>='3') s[k]-=3;
else
{
s[k]+=7;
k--;
while(s[k]=='0')
{
s[k]='9';
k--;
}
s[k]-=1;
}
if(s[0]=='0')
{
s.erase(0, 1);
}
}
Matrix kk=tmp;
kk=kk.quickpow1();
long long ans=(5*kk.element[0][0]+2*kk.element[0][1]+kk.element[0][2])%mod;
printf("%lld\n", ans);
}
return 0;
}
#include<string.h>
#include<cstdio>
#include<iostream>
#define clr(a) memset(a,0,sizeof(a))
using namespace std;
string s, tmp;
const long long mod=1000000007;
typedef long long ll;
struct Ma{
ll a[3][3];
}D,E;
Ma mul(Ma a,Ma b){
Ma ans;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
ans.a[i][j]=0;
for(int k=0;k<3;k++){
ans.a[i][j] += a.a[i][k]*b.a[k][j]%mod;
ans.a[i][j]%=mod;
}
}
}
return ans;
}
Ma Pow(Ma a,ll b){
Ma d=E,t=a;
while(b){
if(b&1) d=mul(d,t);
b>>=1,t=mul(t,t);
}
return d;
}
Ma Pow(Ma a){
int l=s.size();
Ma d=E,t=a;
for(int i=l-1;i>=0;i--){
int j=s[i]-'0';
d=mul(d,Pow(t,j));
t=Pow(t,10);
}
return d;
}
int main(){
//freopen("in.txt", "r", stdin);
//freopen("11.txt", "w", stdout);
clr(D.a),clr(E.a);
for(int i=0;i<=2;i++) E.a[i][i]=1;
D.a[0][0]=2;
D.a[0][2]=3;
D.a[0][1]=D.a[1][0]=D.a[2][1]=1;while(cin>>s)
{
if(s.size()==1)
{
if(s[0]=='1'){
cout<<1<<endl;continue;
}
else if(s[0]=='2')
{
cout<<2<<endl; continue;
}
else if(s[0]=='0')
{
cout<<0<<endl; continue;
}
else if(s[0]=='3')
{
cout<<5<<endl; continue;
}
else s[0]-=3;
}
else
{
int k = s.size()-1;
if(s[k]>='3') s[k]-=3;
else
{
s[k]+=7;
k--;
while(s[k]=='0')
{
s[k]='9';
k--;
}
s[k]-=1;
}
if(s[0]=='0')
{
s.erase(0, 1);
}
}
Ma kk=D;
kk=Pow(kk);
long long ans=(5*kk.a[0][0]+2*kk.a[0][1]+kk.a[0][2])%mod;
printf("%lld\n", ans);
}
return 0;
}