数塔

题目

一个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(){;}
posted @ 2020-07-23 21:51  Ame_sora  阅读(337)  评论(0编辑  收藏  举报