luoguP1397
MonsterAbandon · · 个人记录
原题
数学方法可解
由题可知
由上三式可推得:
同时
·在草稿纸上拿条件推一下就知道了
已知公式之后,先用一点数列的简单(事实)知识处理一下
除法用逆元解决,a=1的情况需要特判一手
然后将花里胡哨的式子替换一下
再处理一下 F[n-1,m]
用和p一样的方法处理一个q
得到F[n,m]
是不是简洁多了
最后考虑一下怎么处理n,m这两大数据
用高精铁超时
这时候就需要抬出大名鼎鼎的费马小定理!
在模数MOD为质数且gcd(a,MOD)=1的前提下(由题目数据范围,a<=1e9,MOD=1e9+7)
处理之后的n和m就缩小到1e9+7之内了,用快速幂就能求出x和a的次方
也要考虑到a和x为1的特殊情况,所以再处理一个n和m取模1e9+7备用
下面是代码:
/*#STAR DOG#*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*十年OI一场空,不开longlong见祖宗*/
typedef double ld;
const ll Mod=100055128505716009;
const int MOD=1e9+7;
const int DD=3e5+114;
ll re(){
ll s=0,w=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') w=-w;ch=getchar();}
while (ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+(ch^'0');ch=getchar();}
return s*w;
}
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=(ans*a)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ans;
}
ll n,m,a,b,c,d;
ll nx,mx,p,q;
ll x,y;
string nn,mm;
int main()
{
cin>>nn;
int len=nn.length();
for(int i=0;i<len;i++){
n=(10*n+nn[i]-'0')%(MOD-1);
nx=(10*nx+nn[i]-'0')%MOD;
}
n=(n-1+MOD-1)%(MOD-1);
nx=(nx-1+MOD)%MOD;
cin>>mm;
len=mm.length();
for(int i=0;i<len;i++){
m=(10*m+mm[i]-'0')%(MOD-1);
mx=(10*mx+mm[i]-'0')%MOD;
}
m=(m-1+MOD-1)%(MOD-1);
mx=(mx-1+MOD)%MOD;
a=re();b=re();c=re();d=re();
ll mi=qpow(a,m);
x=mi*c%MOD;
if(a==1)p=mx*b%MOD;
else{
ll phi=qpow(a-1,MOD-2);
p=(b*(mi-1+MOD)%MOD)*phi%MOD;
}
ll ni=qpow(x,n);
y=(mi*d+p)%MOD;
if(x==1)q=nx*y%MOD;
else q=y*(ni-1+MOD)%MOD*qpow(x-1,MOD-2)%MOD;
printf("%lld",(ni*(mi+p)+q)%MOD);
return 0;
}