整数的lqp拆分-Solution
我们从特殊一点的思考,比如说我们现在有一个长度为 \(n\) 的东西,我们的价值是 \(F_n\),这个价值我们是不是可以等价成个数,因为在上面的骨牌问题中,每个骨牌都是有不一样的颜色的。所以我们可以把他等价成上面一种情况,所以这样的话就很好办了。
那么骨牌的生成函数就是 \(\displaystyle{\frac{x}{1-x-x^2}}\)。那么总的生成函数的柿子就是 \(\displaystyle{\frac{1}{1-\displaystyle{\frac{x}{1-x-x^2}}}}\)。
我们现在需要考虑的问题就是如何化简这个柿子。这不是一件很难的事情。
我们上下同乘 \(1-x-x^2\) 得到
\(\displaystyle{\frac{1-x-x^2}{1-2x-x^2}}\)
首先分离一个常数出来。原式等于
\(1+\displaystyle{\frac{x}{1-2x-x^2}}\)
分式分解。令原式等于
\(\displaystyle{\frac{A}{x-x_1}}+\displaystyle{\frac{B}{x-x_2}}\)
那么我们有了一个方程,解得:
\(\begin{cases}x_1=\sqrt{2}-1 \\ x_2=-1-\sqrt{2} \\ A=\displaystyle{\frac{\sqrt{2}-1}{2\sqrt{2}}} \\ B=\displaystyle{\frac{\sqrt{2}+1}{2\sqrt{2}}} \end{cases}\)
那么原式等于
\(\displaystyle{\frac{\frac{\sqrt{2}+1}{2\sqrt{2}}}{x-\sqrt{2}+1}}+\displaystyle{\frac{\frac{\sqrt{2}-1}{2\sqrt{2}}}{x+\sqrt{2}+1}}\)
后文推导还是写成换元后的形式,因为这实在是太 ex 了
显然左右的上下都可以同时除以 \(x_1,x_2\)。
\(\displaystyle{\frac{A}{x-x_1}}+\displaystyle{\frac{B}{x-x_2}}\)
\(\displaystyle{\frac{A/x_1}{x/x_1-1}}+\displaystyle{\frac{B/x_2}{x/x_2-1}}\)
\(\displaystyle{\frac{-A/x_1}{1-x/x_1}}+\displaystyle{\frac{-B/x_2}{1-x/x_2}}\)
可以把上面的东西就当成一个系数,因为他也只是在生成函数里充当一个系数的成分。下面的显然可以反演回去。那么答案就是
\([x^n]\displaystyle{\frac{-A/x_1}{1-x/x_1}}+[x^n]\displaystyle{\frac{-B/x_2}{1-x/x_2}}\)
\(-\displaystyle{\frac{A}{x_1^{n+1}}}-\displaystyle{\frac{B}{x_2^{n+1}}}\)
我们把我们已经算到的东西带进去把。首先很显然可以先提一个 \(\displaystyle{\frac{1}{2\sqrt{2}}}\)
那么答案就是
\(-\displaystyle{\frac{1}{2\sqrt{2}}}\Big(\displaystyle{\frac{\sqrt{2}-1}{(1-\sqrt{2})^{n+1}}} \Big)-\displaystyle{\frac{1}{2\sqrt{2}}}\Big(\displaystyle{\frac{\sqrt{2}+1}{(1+\sqrt{2})^{n+1}}} \Big)\)
\(\displaystyle{\frac{1}{2\sqrt{2}}}\Big(\displaystyle{\frac{1}{(1-\sqrt{2})^n}} \Big)-\displaystyle{\frac{1}{2\sqrt{2}}}\Big(\displaystyle{\frac{1}{(1+\sqrt{2})^n}} \Big)\)
\(\displaystyle{\frac{1}{2\sqrt{2}}}(1+\sqrt{2})^n-\displaystyle{\frac{1}{2\sqrt{2}}}(1-\sqrt{2})^n\)
\(\displaystyle{\frac{1}{2\sqrt{2}}}\Big((1+\sqrt{2})^n-(1-\sqrt{2})^n \Big)\)
大功告成。但是我们现在还有一个问题,就是 \(\sqrt{2}\) 在规定的模数下逆元是多少。
#include <bits/stdc++.h>
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N=800, inf=0x3f3f3f3f;
int P=1e9+7;
int main(){
for(int i=1;i<=1e9+7;++i){
if((long long)i*i%P==2){
cout<<i<<endl;
}
}
return 0;
}
既然模数一定,那么直接暴力 /se,这份暴力跑的也不慢。
最后代码
#include <bits/stdc++.h>
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N=800, inf=0x3f3f3f3f;
string st[N];
long long ans=0;
const int P=1e9+7,W=940286407;
typedef long long ll;
ll qpow(ll x,long long y){
ll res=1;
while(y){
if(y&1) res=(res*x)%P;
x=(x*x)%P;
y>>=1;
}
return res;
}
int main(){
char ch;
while(cin>>ch){
ans=ans*10+ch-'0';
ans%=P-1;
}
long long pans=qpow(1+W,ans)-qpow(1-W,ans)+P;
pans%=P;
cout<<(pans*qpow(2*W,P-2))%P<<endl;
return 0;
}