数塔
题目
一个n行的数塔,第n行有n个数。最后一行依次为1,2,3...n,第i行的第j个数等于第i+1行第j个数和第j+1个数的和。
输入格式
一行一个数字T表示数据组数
接下来T行,每行一个数字,表示n。
输出格式
输出T行,每行一个数字表示答案。由于答案可能过大,又考虑到各位选手可能对高精充满抵触,因此我们的答案
对998244353取模。
样例
输入
2
2
4
输出
3
20
数据范围
30%的数据,\(n\le 100\) ,\(T\le10\)
50%的数据,\(n\le10000\)
100%的数据,\(n\lt1e18\),\(T\le1000\)
考虑前50%的数据,可以\(O(n)\)递推去做,但是对于后50%的数据,应当用\(O(logn)\)的做法,首先进过一番冷静暴力打表分析,不难看出和组合数有关,现在开始验证
拿n=7为例子
1 2 3 4 5 6 7
3 5 7 9 11 13
8 12 16 20 24
20 28 36 44
48 64 80
112 144
256
考虑设第一层为\(a_1\)~\(a_7\),3为\(a_1\)+\(a_2\),8为\(a_1\)+\(2a_2\)+\(a_3\),20为\(a_1\)+\(3a_2\)+\(3a_3\)+\(a_4\),符合组合数金字塔(杨辉三角)的形式,所以考虑柿子为
\(\begin{aligned}\sum_{i=0}^{n-1}C_{n-1}^{i}(i+1)\end{aligned}\),将i+1分开为\(\begin{aligned}\sum_{i=0}^{n-1}C_{n-1}^{i}*i+\sum_{i=0}^{n-1}C_{n-1}^{i}\end{aligned}\)将前面的c提出来一个\(\frac {n-1}i\)变为\(\begin{aligned}n-1*\sum_{i=0}^{n-1}C_{n-2}^{i-1}+\sum_{i=0}^{n-1}C_{n-1}^{i}\end{aligned}\)即为\((n-1)*2^{n-2}+2^{n-1}\)
然后就可以过了这个题
#include<bits/stdc++.h>
using namespace std;
#define LL long long
template <typename T> void read(T & t){
t = 0;int f = 1;char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')f =- 1;ch = getchar();}
do{t = t * 10 + ch - '0';ch = getchar();}while(ch >= '0' && ch <= '9');t *= f;
}
#define mod 998244353
LL t , n;
inline LL quick_pow(LL a , LL b){
LL res = 1;
for(; b ; b >>= 1 , a = a * a % mod){
if(b & 1){
res = res * a % mod;
}
}
return res % mod;
}
inline int Ame_(){
read(t);
for(; t --> 0 ;){
read(n);
if(n == 1){
puts("1");
}
else{
LL ans = 1;
ans = quick_pow(2 , n - 1) % mod + (n - 1) % mod * quick_pow(2 , n - 2) % mod;
printf("%lld\n" , ans % mod);
}
}
return 0;
}
int Ame__ = Ame_();
int main(){;}