FJOI2007 轮状病毒
传送门:https://www.luogu.org/problemnew/show/P2144
暴力找规律
发现n=1~5时答案是1,5,16,45,121
奇数项是平方数,偶数项是平方数减4
1,5,16,45,121 分别是1^2,3^2-4,4^2,7^2-4,11^2
1,3,4,7,11这个数列有类似于斐波那契数列的性质,只不过前两项是1和3罢了
那么我们就可以递推求这个类斐波那契数列的第n项,然后平方,然后再根据n的奇偶来决定是否减4
高精度代码如下
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<iostream>
#include<cstdlib>
using namespace std;
class Bigint{
public:
int size,num[10000];
Bigint(){
size=0;
memset(num,0,sizeof(num));
}
Bigint(int data)
{
size=0;
while(data!=0)
{
size++;
num[size]=data%10;
data/=10;
}
}
void init(int data)
{
size=0;
while(data!=0)
{
size++;
num[size]=data%10;
data/=10;
}
}
};
Bigint operator + (Bigint A,Bigint B){
Bigint ans;
int s=max(A.size,B.size);
ans.size=s;
for(int i=1;i<=s;i++)
ans.num[i]=A.num[i]+B.num[i];
for(int i=1;i<=s;i++)
if(ans.num[i]>=10)
{
ans.num[i+1]+=ans.num[i]/10;
ans.num[i]%=10;
}
if(ans.num[s+1]!=0)
ans.size++;
return ans;
}
Bigint operator - (Bigint A,Bigint B){
Bigint ans;
int s=max(A.size,B.size);
ans.size=s;
for(int i=1;i<=s;i++)
ans.num[i]=A.num[i]-B.num[i];
for(int i=1;i<=s;i++)
if(ans.num[i]<0)
{
ans.num[i+1]--;
ans.num[i]=(ans.num[i]+10)%10;
}
while(ans.num[ans.size]==0)
ans.size--;
return ans;
}
Bigint operator * (Bigint A,Bigint B){
Bigint ans;
int s1=A.size,s2=B.size;
for(int i=1;i<=s1;i++)
for(int j=1;j<=s2;j++)
ans.num[i+j-1]+=A.num[i]*B.num[j];
int s=s1+s2-1;
int k=1;
while(ans.num[k]!=0||k<=s)
{
ans.num[k+1]+=ans.num[k]/10;
ans.num[k]%=10;
k++;
}
if(ans.num[k]==0)k--;
ans.size=k;
return ans;
}
ostream & operator << (ostream &os,Bigint A){
int s=A.size;
for(int i=s;i>=1;i--)
os<<A.num[i];
return os;
}
Bigint P,Q,ANS;
int n;
int main(){
cin>>n;
P.init(1);
Q.init(3);
for(int i=3;i<=n;i++)
{
if(i%2)P=P+Q;
else Q=P+Q;
}
if(n%2)ANS=P;
else ANS=Q;
ANS=ANS*ANS;
if(n%2==0)ANS=ANS-4;
cout<<ANS<<endl;
return 0;
}
LLAP.