【题目描述】:
【题目解法】:
裸的矩阵乘法,由于n m比较大,我又不知道能不能用femat小定理,所以我们直接硬上十进制快速幂辣
然后就被卡常数了QwQ
算了TAT,手动矩阵转移,我们发现3*3里面有一行的值是不会变的,我们可以手动转移其它6个值
还是TLE?我上Contest Hunter上交了一发,2s+AC?
大新闻:bzoj没有Contest Hunter快?(大雾弥漫)
然后将int改成longlong,去掉一堆%P总算是10s+A掉了TAT
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1000005;
const long long maxmod=2012182013;
struct node
{
long long a1,a2,a3;
long long a4,a5,a6;
// 0, 0, 1
inline void clear() {a1=a2=a3=a4=a5=a6=0;}
inline void init() {clear(); a1=a5=1;}
inline node operator * (const node &a)
{
node b;
b.a1=(a1*a.a1+a2*a.a4)%maxmod;
b.a2=(a1*a.a2+a2*a.a5)%maxmod;
b.a3=(a1*a.a3+a2*a.a6+a3)%maxmod;
b.a4=(a4*a.a1+a5*a.a4)%maxmod;
b.a5=(a4*a.a2+a5*a.a5)%maxmod;
b.a6=(a4*a.a3+a5*a.a6+a6)%maxmod;
return b;
}
};
struct Node {int a[N],len;} n,m;
int a,b,c,d,e,f; node ans,fac[10]; Node tmp;
inline long long GetInt()
{
long long x=0; char c=getchar();
while ((c!='-')&&((c<'0')||(c>'9'))) c=getchar();
while ((c>='0')&&(c<='9')) x=(x*10+(long long)(c-'0'))%maxmod,c=getchar();
return x;
}
void init()
{
char ch=getchar();
for (; (ch<'0')||(ch>'9'); ch=getchar());
for (n.len=0; (ch>='0')&&(ch<='9'); ch=getchar()) n.a[++n.len]=ch-'0';
for (; (ch<'0')||(ch>'9'); ch=getchar());
for (m.len=0; (ch>='0')&&(ch<='9'); ch=getchar()) m.a[++m.len]=ch-'0';
for (int i=1; i<=n.len/2; i++) swap(n.a[i],n.a[n.len-i+1]);
for (int i=1; i<=m.len/2; i++) swap(m.a[i],m.a[m.len-i+1]);
a=GetInt(); b=GetInt(); c=GetInt(); d=GetInt(); e=GetInt(); f=GetInt();
}
inline void sub()
{
tmp.a[1]--;
for (int i=1; (i<=tmp.len)&&(tmp.a[i]<0); i++) tmp.a[i+1]--,tmp.a[i]+=10;
for (; (tmp.len>1)&&(tmp.a[tmp.len]==0); tmp.len--);
}
inline node Mul(node a)
{
int b=10; node nowans; nowans.init();
for (;b;b/=2,a=a*a) if (b%2==1) nowans=nowans*a;
return nowans;
}
inline node calc(node a,Node b)
{
node nowans; nowans.init(); fac[0].init();
for (int i=1; i<=9; i++) fac[i]=fac[i-1]*a;
for (int i=b.len; i>=1; i--) nowans=Mul(nowans)*fac[b.a[i]];
return nowans;
}
void solve()
{
ans.init();
tmp.len=m.len; for (int i=1; i<=m.len; i++) tmp.a[i]=m.a[i]; sub(); sub();
ans=calc((node){b,a,c,1,0,0},tmp); node nowans=ans;
ans=ans*(node){e,d,f,1,0,0}*(node){e,d,f,1,0,0};
tmp.len=n.len; for (int i=1; i<=n.len; i++) tmp.a[i]=n.a[i]; sub();
ans=calc(ans,tmp); ans=ans*nowans;
printf("%lld\n",((long long)ans.a1+(long long)ans.a2+(long long)ans.a3)%maxmod);
}
int main()
{
init();
solve();
return 0;
}