数学推导公式只80分,救命
查看原帖
数学推导公式只80分,救命
386890
Kogenta楼主2021/10/13 16:06

首先我们关注同一行的递推式:

F[i][m]=(...(((F[i][1]a+b)a+b)a+b)...)a+bF[i][m]=(...(((F[i][1]*a+b)*a+b)*a+b)...)*a+b =F[i][1]am1+i=0m2bai=F[i][1]*a^{m-1}+\sum_{i=0}^{m-2} ba^i =F[i][1]am1+bam11a1=F[i][1]*a^{m-1}+b\frac{a^{m-1}-1}{a-1}

则从一行推到下一行:

F[i+1][1]=cF[i][m]+dF[i+1][1]=c*F[i][m]+d =F[i][1]am1c+bcam11a1+d=F[i][1]*a^{m-1}c+bc\frac{a^{m-1}-1}{a-1}+d

观察到 F[i+1][1]F[i+1][1] 的系数为 am1ca^{m-1}c 且常数项为 bcam11a1+dbc\frac{a^{m-1}-1}{a-1}+d ,均为定值,不妨设 k=am1ck=a^{m-1}ct=bcam11a1+dt=bc\frac{a^{m-1}-1}{a-1}+d ,则式子变成了如下形式:

F[i+1][1]=F[i][1]k+tF[i+1][1]=F[i][1]*k+t

类似(1)(1)式,有如下推导:

F[n][1]=(...(((F[1][1]k+t)k+t)k+t)...)k+tF[n][1]=(...(((F[1][1]*k+t)*k+t)*k+t)...)*k+t =F[1][1]kn1+i=0n2tki=F[1][1]*k^{n-1}+\sum_{i=0}^{n-2}tk^i =F[1][1]kn1+tkn11k1=F[1][1]*k^{n-1}+t\frac{k^{n-1}-1}{k-1}

再套用(1)(1)式,得到最终答案(F[n][1]F[n][1]就不代入了):

F[n][m]=F[n][1]am1+bam11a1F[n][m]=F[n][1]*a^{m-1}+b\frac{a^{m-1}-1}{a-1}

其中n,mn,m作为固定的乘方数,除法可用费马小定理换做乘其逆元,可用费马小定理 ap11(modp)a^{p-1}\equiv1\pmod{p} 优化,将高精数对 1e9+61e9+6 取模,a=1a=1时也有特判,可是最终提交上去仅有80pts80pts (WA的是3,9,13,173,9,13,17四个点),完全不用担心时间问题(已经快到起飞了),求大佬帮忙看看还有什么漏洞没有...(代码贴在下边)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9,tmod=1e9+7;
ll n[2][200010],nrec[2][200010],n1[2],nrec1[2];
string str[2];
void modd(int id){
	int res=n[id][0];
	for(int i=res;i>=1;i--){
		n[id][i]%=(tmod-1);
		if(i>1){
			n[id][i-1]+=n[id][i]*mod;
			n[id][i]=0;
		}
	}
	return ;
}
void modd1(int id){
	int res=nrec[id][0];
	for(int i=res;i>=1;i--){
		nrec[id][i]%=tmod;
		if(i>1){
			nrec[id][i-1]+=nrec[id][i]*mod;
			nrec[id][i]=0;
		}
	}
	return ;
}
void rd(int s,int r){
	ll ans=0,now=1;
	for(int i=str[s].length()-1;i>=0;i--){
		ans+=now*((ll)str[s][i]-48);
		now*=10;
		if(now>=mod){
			n[r][++n[r][0]]=ans;
			ans=0;
			now=1;
		}
	}
	if(ans){
		n[r][++n[r][0]]=ans;
	}
	for(int i=0;i<=n[r][0];i++)nrec[r][i]=n[r][i];
	modd(r);
	modd1(r);
	n1[r]=n[r][1]%tmod;
	nrec1[r]=nrec[r][1]%tmod;
	return ;
}
ll enpow(ll x,ll y){
	ll base=x,t=y,ans=1ll;
	while(t){
		if(t&1){
			ans=ans*base%tmod;
		}
		base=base*base%tmod;
		t>>=1;
	}
	return ans;
}
ll mul(ll x,int id){
	return x*nrec1[id]%tmod;
}
int main(){
	ll a,b,c,d;
	cin>>str[0]>>str[1]>>a>>b>>c>>d;
	for(int id=0;id<=1;id++){
		for(int i=str[id].length()-1;i>=0;i--){
			if(str[id][i]=='0'){
				if(i==1){
					str[id]=str[id].substr(1,str[id].length()-1);
					break;
				}
				else{
					str[id][i]='9';
				}
			}
			else{
				str[id][i]-=1;
				break;
			}
		}
	}
	rd(0,0),rd(1,1);
	ll a1=enpow(a,n1[1]),c1=enpow(c,n1[0]);
	ll rp;
	if(a>1){
		rp=b*(a1-1)%tmod*enpow(a-1,tmod-2)%tmod;
	}
	else rp=mul(b,1);
	ll a2=a1*c%tmod,r=(rp*c%tmod+d)%tmod;
	ll res=enpow(a2,n1[0]);
	ll ans=r;
	if(res>1&&a2>1)ans=ans*((res-1)*enpow(a2-1,tmod-2)%tmod)%tmod;
	ans=(ans+res)%tmod;
	ans=ans*a1%tmod;
	ans=ans+rp;
	cout<<(ans%tmod+tmod)%tmod<<endl;
	return 0;
}
2021/10/13 16:06
加载中...