Suma de Fibonacci (Suma binomial)

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquí
Es muy difícil pensar que no he escrito una pregunta similar antes. El centro de pruebas es resumir y optimizar la ecuación con el binomio. Especialmente la ecuación de optimización aquí es un pozo real.
No hay mucha tontería, empuje hacia el proceso:
porque:
Inserte la descripción de la imagen aquí
puede haber:
Inserte la descripción de la imagen aquí
así que hay una expansión binomial:

Inserte la descripción de la imagen aquí
Obviamente, es proporcional, por lo que la complejidad se puede cambiar a klogn;
entonces el resultado de la fórmula S se puede obtener como:

Inserte la descripción de la imagen aquí
Dado que se requiere mod1e9 + 9, se puede saber del pequeño teorema de Fermat que la transformación es:

Inserte la descripción de la imagen aquí

Tanto el valor de qi como el valor de factorial se pueden preprocesar, pero encontrará que T se escribe directamente con esta fórmula. Este es un poder realmente rápido de tarjetas anormales. . . . . . . . .
Este es mi código de tiempo de espera:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll P = 1e9+9;
const ll maxn = 1e5+5;
ll a[maxn],b[maxn],jie[maxn];
void pre(){
    
    
	jie[0]=1;
	//预处理阶乘
	for(ll i=1;i<maxn;i++)jie[i]=jie[i-1]*i%P;
	//预处理a,b
	a[0]=1;b[0]=1;
	for(ll i=1;i<maxn;i++){
    
    
		a[i]=a[i-1]*691504013%P;//a的%P的逆元
		b[i]=b[i-1]*308495997%P;//b的%p的逆元
	}
}
ll QP(ll x,ll n){
    
    
      ll res=1;
      while(n){
    
    
      	if(n&1){
    
    
      		 res=res*x%P;
		  }
		  x=x*x%P;
		  n>>=1;
	  }
	  return res;
}
ll T;
ll N,C,K;
int main(){
    
    
	scanf("%lld",&T);
	pre();
	ll ans=0;
		 ll x=QP(383008016,P-2);//利用费马小定理求1/sqrt(5)%P的值
		  
	while(T--){
    
    
	     ans=0;
		scanf("%lld %lld %lld",&N,&C,&K);
		ll t=QP(a[K],C)%P;
		for(ll i=0;i<=K;i++){
    
    
			ll fenzi=jie[K];
			ll fenmu=jie[i]*jie[K-i]%P;
			ll res=fenzi*QP(fenmu,P-2)%P;
			ll temp=t*(QP(t,N)-1)%P*QP(t-1,P-2)%P;//这里有个十分奇葩的地方,我开头把他分开写居然wa了而不是T了。。。。。。。
			if(t==1){
    
    //分母没有意义,求和可知为N 
				temp=N%P;
			}
			temp=temp*res%P;
			if(i&1) ans-=temp;//如果为负数
			else ans+=temp;//如果为正数
			ans%=P;
		}

	 ans=QP(x,K)*ans%P;
	 ans=(ans%P+P)%P;//防止负数
	 printf("%lld\n",ans);
	}
	
	return 0;
} 

Entonces estaba tan confundido, ¿cómo sucedió esto? ? ? ? ? colapso. . . . . . .
Consulte la optimización del código del tipo grande porque el valor de la siguiente q es el valor de la q anterior multiplicado por A (-C) * B ^ C;
código AC:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
const ll mod=1e9+9;
const ll MAXN=1e5;
ll factor[MAXN+10];
ll invFactor[MAXN+10];
ll invn[MAXN+10];
const ll A=691504013;
const ll invA=691504012;
const ll B=308495997;
const ll D=276601605;
ll QP(ll x, ll n)
{
    
    
    ll res=1;
    while(n)
    {
    
    
        if (n&1) res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}
ll Mod(ll a, ll b)
{
    
    
    a+=b;
    if (a>=mod)
        a-=mod;
    return a;
}
void pre()
{
    
    
    factor[0]=invFactor[0]=invn[0]=factor[1]=invFactor[1]=invn[1]=1;
    for(int i=2; i<=MAXN; i++)
    {
    
    
        factor[i]=factor[i-1]*i%mod;
        invn[i]=(ll) (mod-mod/i)*invn[mod%i]%mod;
        invFactor[i]=invFactor[i-1]*invn[i]%mod;
    }
}
ll getC(ll m, ll n)//求C(n,m) 
{
    
    
    if (n<0 || m<0 || m>n)
        return 0;
    ll ans=factor[n];
    ans=(ll) ans*invFactor[m]%mod;
    ans=(ll) ans*invFactor[n-m]%mod;
    return ans;
}
int main()
{
    
    
    pre();
    int T;
    scanf("%d", &T);
    while(T--)
    {
    
    
        ll n, c, k;
        scanf("%lld%lld%lld", &n, &c, &k);
        ll ans=0;
        ll a1=QP(QP(A, k), c%(mod-1));
        ll q=QP((ll) invA*B%mod, c%(mod-1));
        ll n1=n%mod;
        ll n2=n%(mod-1);
        ll a1power=QP(a1, n2);
        ll qpower=QP(q, n2);
        for(int i=0; i<=k; i++)
        {
    
    
            ll sum=getC(i, k);
            if (i&1)
            {
    
    
                sum=mod-sum;
            }
            if (a1==1)
            {
    
    
                ans=(ans+sum*n1%mod)%mod;
            }
            else
            {
    
    
                sum=sum*(a1*(a1power-1+mod)%mod)%mod;
                sum=sum*QP(a1-1, mod-2)%mod;
                ans=Mod(ans, sum);
            }
            a1=a1*q%mod;
            a1power=a1power*qpower%mod;
        }
        printf("%lld\n",ans*QP(D,k)%mod);
    }
}

Es inesperado. . . . . . .

Supongo que te gusta

Origin blog.csdn.net/qq_44555205/article/details/107579808
Recomendado
Clasificación