题目描述
来来来 喝完这一杯,还有一杯
再喝完这一杯,还有三杯
enterdawn想找到突然的自我,前面几次分别喝了1,1,3,5,9,15,25,41杯。
现有T次询问,请求出某一次的时候enterdawn一共喝了多少杯。
提示:前两项固定是1。
输入描述:
第一行为一个整数T(1≤T≤1000),为样例组数。 每组样例只包含一个整数n(1≤n≤1e6),表示询问enterdawn在第n次时一共喝了多少杯。
输出描述:
输出一个整数,表示enterdawn在第n次时一共喝了多少杯。 由于数据可能很大,所以输出需要对114514919810取模。
示例1
输入
5 1 2 3 4 5
输出
1 2 5 10 19
本题的中心就是找到每次喝多少杯的规律
(1)
题目当中给的数: 1,1,3,5,9,15,25,41
相邻两项的差:0,2,2,4,6,10,16;
明显可以看出从第三个开始,相邻两项的差等于前两个相邻两项的差的和
2=0+2;
4=2+2;
6=2+4;
......
进而可以得出:a[i]=a[i-1]+a[i-1]-a[i-2]+a[i-2]+a[i-3];
即:a[i]=a[i-1]+a[i-1]-a[i-3];
(2)
还有一种就是观察出来的:
从第三项开始 :a[i]=a[i-1]+a[i-2]+1;
其次就是对数据进行预处理求前缀和
s[i]=s[i-1]+a[i](i>=2);
参考代码如下:
数据较大记得取模,开long long;
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll N=1e6+10,mod=114514919810;
ll a[N];
ll s[N];
ll t;
void dyh()
{
a[1]=1;a[2]=1;a[3]=3;
s[1]=1;s[2]=2;s[3]=5;
for(int i=4;i<=1000001;i++)
{
a[i]=((a[i-1]%mod)*2-a[i-3]%mod+mod)%mod;
//或者:
// a[i]=(a[i-1]+a[i-2]+1)%mod;
s[i]=(s[i-1]+a[i])%mod;
}
}
int main()
{
cin>>t;
dyh();
while(t--)
{
int x;
cin>>x;
cout<<s[x]%mod<<endl;
}
return 0;
}