Project Euler #356

传送门ber~

Duan2baka在外地找不到脚头的地方

题中 g ( x ) = x 3 − 2 n x 2 + n g(x)=x^3-2^nx^2+n g(x)=x32nx2+n可以看作是降幂的形式,即 x 3 = 2 n x 2 − n x^3=2^nx^2-n x3=2nx2n
x k = x k − 3 ⋅ x 3 = x k − 3 ⋅ ( 2 n x 2 − n ) = 2 n x k − 1 − n x k − 3 x^k=x^{k-3}\cdot x^3=x^{k-3}\cdot(2^nx^2-n)=2^nx^{k-1}-nx^{k-3} xk=xk3x3=xk3(2nx2n)=2nxk1nxk3
A ( k ) = x k A(k)=x^k A(k)=xk,那么有 A ( k ) = 2 n A ( k + 1 ) − n f ( x − 3 ) A(k)=2^nA(k+1)-nf(x-3) A(k)=2nA(k+1)nf(x3),可以矩阵乘法求得 A ( 0 ) , A ( 1 ) , A ( 2 ) A(0),A(1),A(2) A(0),A(1),A(2)的系数
可是很遗憾,即使知道系数,我们也不能很轻松的求得 A ( 1 ) A(1) A(1) A ( 2 ) A(2) A(2)的值
我们换个思路,设 g ( x ) g(x) g(x)的三个根分别为 a , b , c a,b,c a,b,c,令 f ( x ) = a x + b x + c x f(x)=a^x+b^x+c^x f(x)=ax+bx+cx,递推式和上面的很明显是一样的

f ( 0 ) = 3 f(0)=3 f(0)=3显然,接下来我们要算 f ( 1 ) f(1) f(1) f ( 2 ) f (2) f(2)的值
( x − a ) ( x − b ) ( x − c ) = x 3 − 2 n x 2 + n (x-a)(x-b)(x-c)=x^3-2^nx^2+n (xa)(xb)(xc)=x32nx2+n,待定系数, a + b + c = 2 n a+b+c=2^n a+b+c=2n, a b + b c + c a = 0 ab+bc+ca=0 ab+bc+ca=0
所以 f ( 1 ) = a + b + c = 2 n f(1)=a+b+c=2^n f(1)=a+b+c=2n, f ( 2 ) = f ( 1 ) 2 − 2 ( a b + b c + c a ) = 4 n f(2)=f(1)^2-2(ab+bc+ca)=4^n f(2)=f(1)22(ab+bc+ca)=4n
我们可以很轻松的求出 f ( 987654321 ) f(987654321) f(987654321)
那怎么通过 a 987654321 + b 987654321 + c 987654321 a^{987654321}+b^{987654321}+c^{987654321} a987654321+b987654321+c987654321求出最大根 c c c c 987654321 c^{987654321} c987654321

我们观察一下根的分布
几何画板发现三个根分别在 ( − 1 , 0 ) ( 0 , 1 ) ( 2 n − 1 , 2 n ) (-1,0)(0,1)(2^n-1,2^n) (1,0)(0,1)(2n1,2n)
让我们瞎jb证一下。。。。
g ( 0 ) = n > 0 , g ( 1 ) = 1 − 2 n + n < 0 , g ( − 1 ) = − 1 − 2 n + n < 0 g(0)=n>0,g(1)=1-2^n+n<0,g(-1)=-1-2^n+n<0 g(0)=n>0,g(1)=12n+n<0,g(1)=12n+n<0,所以 ( − 1 , 0 ) ( 0 , 1 ) (-1,0)(0,1) (1,0)(0,1)存在两根;
化简方程 g ( x ) = x 2 ( x − 2 n ) + n g(x)=x^2(x-2^n)+n g(x)=x2(x2n)+n x x x 2 n 2^n 2n g ( x ) = n > 0 g(x)=n>0 g(x)=n>0 x x x 2 n − 1 2^n-1 2n1 g ( x ) = − ( 2 n − 1 ) 2 + n < 0 g(x)=-(2^n-1)^2+n<0 g(x)=(2n1)2+n<0,所以必存在一根
a < b < c a<b<c a<b<c a 987654321 + b 987654321 a^{987654321}+b^{987654321} a987654321+b987654321 < 1 <1 <1

a 3 − 2 n a 2 + n = 0 a^3-2^na^2+n=0 a32na2+n=0,所以 − a 3 − 2 n a 2 + n > 0 -a^3-2^na^2+n>0 a32na2+n>0,所以 ∣ b ∣ > ∣ a ∣ |b|>|a| b>a 0 < a 987654321 + b 987654321 < 1 0<a^{987654321}+b^{987654321}<1 0<a987654321+b987654321<1

所以所求的 ⌊ c 987654321 ⌋ = f ( 987654321 ) − 1 \lfloor c^{987654321} \rfloor =f(987654321)-1 c987654321=f(987654321)1

代码如下:

#include<bits/stdc++.h>
#define int long long
#define N 1000020
using namespace std;
inline int read(){
    int x=0,f=1;char c;
    do c=getchar(),f=f=c=='-'?-1:f; while(!isdigit(c));
    do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
    return x*f;
}
const int MOD=1e8;
const int paower=987654321;
int pw[N];
int ans;
struct Matrix{
    int a[4][4];
    Matrix(){memset(a,0,sizeof a);}
    inline void init(int n){
        memset(a,0,sizeof a);
        a[2][1]=1;a[3][2]=1;
        a[1][3]=MOD-n;a[3][3]=pw[n];
    }
    inline Matrix operator * (const Matrix &b){
        Matrix c;
        memset(c.a,0,sizeof c.a);
        for(int t=1;t<=3;t++)
            for(int i=1;i<=3;i++)
                for(int j=1;j<=3;j++)
                    (c.a[i][j]+=1ll*a[i][t]*b.a[t][j]%MOD)%=MOD;
        return c;
    } 
}a,tmp;
inline Matrix qpow(Matrix a,int k){
    Matrix sum=a;k--;
    while(k){
        if(k&1) sum=sum*a;
        a=a*a;
        k>>=1;
    }
    return sum;
}
 main(){
    for(int i=pw[0]=1;i<=30;i++) pw[i]=pw[i-1]<<1;
    for(int i=1;i<=30;i++){
        a.init(i);
        tmp=qpow(a,paower-2);
        ans=(ans+3ll*tmp.a[1][3]%MOD+1ll*pw[i]*tmp.a[2][3]%MOD+1ll*pw[i]*pw[i]%MOD*tmp.a[3][3]%MOD+MOD-1)%MOD;
    }
    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值