Logs Stacking
Description
Daxinganling produces a lot of timber. Before loading onto trains, the timberjacks will place the logs to some place in the open air first. Looking from the sideway, the figure of a logs stack is as follows:
![]() We have known that the number of logs in each layer is fewer than the lower layer for at least one log, and that in each layer the logs are connected in a line. In the figure above, there are 12 logs in the bottom layer of the stack. Now, given the number of logs in the bottom layer, the timberjacks want to know how many possible figures there may be. Input
The first line of input contains the number of test cases T (1 <= T <= 1000000). Then T lines follow. Every line only contains a number n (1 <= n <= 2000000000) representing the number of logs in the bottom layer.
Output
For each test case in the input, you should output the corresponding number of possible figures. Because the number may be very large, just output the number mod 10^5.
Sample Input 4 1 2 3 5 Sample Output 1 2 5 34 Source
POJ Monthly--2006.01.22,anonymous
|
[Submit] [Go Back] [Status] [Discuss]
题解:递推找规律。
f[i]表示底层为i的答案。
f[i]=f[i-1]+f[i-2]*2+f[i-3]*3+...+f[1]*(i-1)+1
可以发现每次是在f[i]的基础上加了sum[i-1]=f[1]+f[2]+...+f[i-1]
这样就可以O(n)递推。
f[i]=f[i-1]+sum[i-1]
sum[i]=sum[i-1]+f[i]
发现可以构造矩阵
{f[i-1],sum[i],f[i]}* { 1 1 0
1 2 1
0 0 0 }
可以矩阵乘法依然不可以,所以只能找规律了。
发现f[i]数组是循环的,循环节是75000
其实f[i]=fib[2*i-1] (fib 斐波那契数列 1,1,2,3,5,8,13 ) 找fib的循环节
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 1000003
#define p 100000
#define M 75000
using namespace std;
int n,m,f[M+3],sum[M+3];
int main()
{
freopen("a.in","r",stdin);
freopen("my.out","w",stdout);
scanf("%d",&n);
f[0]=1;
f[1]=1; sum[1]=1;
for (int i=2;i<=75000;i++)
f[i]=(f[i-1]+sum[i-1])%p,sum[i]=(sum[i-1]+f[i])%p;
for (int i=1;i<=n;i++){
int x; scanf("%d",&x);
printf("%d\n",f[x%M]);
}
}
矩阵乘法的代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define N 1000003
#define p 100000
using namespace std;
int n,m,f[N],sum[N],num[N];
struct data
{
int x,pos,ans;
}a[N];
struct vec{
int a[10][10];
}e,t,ans,ans1;
int cmp(data a,data b)
{
return a.x<b.x;
}
vec mul(vec a,vec b)
{
vec c;
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++)
{
c.a[i][j]=0;
for (int k=1;k<=3;k++)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%p)%p;
}
return c;
}
void change(vec &a,vec b)
{
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++)
a.a[i][j]=b.a[i][j];
}
vec quickpow(vec &ans,vec t,int x)
{
vec base;
change(base,t);
while (x)
{
if (x&1) ans=mul(ans,base);
x>>=1;
base=mul(base,base);
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("my.out","w",stdout);
/*scanf("%d",&n);
f[1]=1; sum[1]=1;
for (int i=2;i<=200000;i++)
f[i]=(f[i-1]+sum[i-1])%p,sum[i]=(sum[i-1]+f[i])%p;
for (int i=1;i<=n;i++){
int x; scanf("%d",&x);
printf("%d\n",f[x]);
}*/
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i].x),a[i].pos=i;
sort(a+1,a+n+1,cmp);
t.a[1][1]=1; t.a[1][2]=1; t.a[1][3]=0;
t.a[2][1]=1; t.a[2][2]=2; t.a[2][3]=1;
t.a[3][1]=0; t.a[3][0]=0; t.a[3][3]=0;
ans.a[1][1]=0; ans.a[1][2]=1; ans.a[1][3]=0;
for (int i=1;i<=3;i++) ans1.a[i][i]=1;
a[0].x=1;
for (int i=1;i<=n;i++)
{
quickpow(ans1,t,a[i].x-a[i-1].x);
num[a[i].pos]=(ans.a[1][1]*ans1.a[1][2]%p+ans.a[1][2]*ans1.a[2][2]%p)%p;
}
for (int i=1;i<=n;i++)
printf("%d\n",num[i]);
}