暴毙了,比较自闭的心理,有点崩溃..
LINK:幸福 一道曾经的我肯定能写出来的 但是我心态崩了 所以没有推出来。
求 $T_n =\displaystyle \sum_{i=0}^{n}F_n$ 其中 $Fn=\displaystyle \sum_{i=0}^{n}f_i \times f_{n-i}$
其中$f$是斐波那契数列 $f_0=1,f_1=1$... 求 $F_n$ 其中n<=1e18
一个比较显然的思路是把Tn 写出来不断化简 最后发现是一个前缀和的形式 然后发现可以O(n)计算了。
这样只有70分的垃圾成绩。
//#include<bits/stdc++.h> #include<iomanip> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<deque> #include<cmath> #include<ctime> #include<cstdlib> #include<stack> #include<algorithm> #include<vector> #include<cctype> #include<utility> #include<set> #include<bitset> #include<map> #define INF 1000000010 #define ll long long #define mp(x,y) make_pair(x,y) #define un unsigned #define db double #define EPS 1e-5 #define mod 998244353 using namespace std; char buf[1<<15],*fs,*ft; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline ll read() { ll x=0,f=1;char ch=getc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();} return x*f; } const ll MAXN=1000010; ll n; ll ans,sum; ll f[MAXN]; signed main() { //freopen("1.in","r",stdin); n=read(); f[0]=1;f[1]=1; for(ll i=2;i<=n;++i)f[i]=(f[i-1]+f[i-2])%mod; if(n<=20000) { for(ll i=0;i<=n;++i) { for(ll j=0;j<=i;++j) ans=(ans+f[j]*f[i-j])%mod; } printf("%lld\n",ans); return 0; } if(n<=1000000) { for(int i=0;i<=n;++i)sum=(sum+f[i])%mod; for(int i=0;i<=n;++i) { sum=((sum-f[n-i+1])+mod)%mod; ans=(ans+f[i]*sum%mod)%mod; } printf("%lld\n",ans); return 0; } //考虑 100分 容斥还没有想好 自闭 printf("%lld\n",ans); return 0; }
继续思考如何优化 发现这个其实是倒三角求和 扩大两倍是不正确的 所以我当时 算2h然后弃疗了。思考方向不是太对。
观察一下$F_n$这个式子。 简单的 化简成 $F_n=\sum_{i=0}^{n-2}f_i \times f_{n-i}+f_{n-1}f_1+f_nf_0$