G. Hits Different

G. Hits Different

In a carnival game, there is a huge pyramid of cans with $2023$ rows, numbered in a regular pattern as shown.

If can $9^2$ is hit initially, then all cans colored red in the picture above would fall.

You throw a ball at the pyramid, and it hits a single can with number $n^2$. This causes all cans that are stacked on top of this can to fall (that is, can $n^2$ falls, then the cans directly above $n^2$ fall, then the cans directly above those cans, and so on). For example, the picture above shows the cans that would fall if can $9^2$ is hit.

What is the sum of the numbers on all cans that fall? Recall that $n^2 = n \times n$.

Input

The first line contains an integer $t$ ($1 \leq t \leq 1000$) — the number of test cases.

The only line of each test case contains a single integer $n$ ($1 \leq n \leq 10^6$) — it means that the can you hit has label $n^2$.

Output

For each test case, output a single integer — the sum of the numbers on all cans that fall.

Please note, that the answer for some test cases won't fit into 32-bit integer type, so you should use at least 64-bit integer type in your programming language (like long long for C++). For all valid inputs, the answer will always fit into 64-bit integer type.

Example

input

10
9
1
2
3
4
5
6
10
1434
1000000

output

156
1
5
10
21
39
46
146
63145186
58116199242129511

Note

The first test case is pictured in the statement. The sum of the numbers that fall is $$1^2 + 2^2 + 3^2 + 5^2 + 6^2 + 9^2 = 1 + 4 + 9 + 25 + 36 + 81 = 156.$$

In the second test case, only the can labeled $1^2$ falls, so the answer is $1^2=1$.

In the third test case, the cans labeled $1^2$ and $2^2$ fall, so the answer is $1^2+2^2=1+4=5$.

In the fourth test case, the cans labeled $1^2$ and $3^2$ fall, so the answer is $1^2+3^2=1+9=10$.

In the fifth test case, the cans labeled $1^2$, $2^2$, and $4^2$ fall, so the answer is $1^2+2^2+4^2=1+4+16=21$.

 

解题思路

  我们先对金字塔转换成矩阵的形式,结果如下图:

  以上图为例子,如果选择$13$号的格子,此时对应的坐标为$(5,3)$(矩阵坐标系)。那么在金字塔中的上一行与$13$号格子有接触的是$8$号和$9$号格子,因此我们想到能不能利用$8$号和$9$号格子的结果来得到$13$号格子的结果呢?

  定义$f(x)$表示从$x$号格子往上能走到的与其接触的格子的值之和。先给出结论,$f(13) = 13^2 + f(8) + f(9) - f(5)$。为什么要减去一个$f(5)$?这是因为从$8$号格子往上走会经过$4$号格子与$5$号格子,从$9$号格子往上走会经过$5$号格子与$6$号格子,因此$f(8)+f(9)$会有重复的部分,即$f(5)$,因此减去即可,有容斥原理的思想在里面。

  递推公式知道了,那么接下来问题是我知道了$x$号格子,怎么得到上面的两个格子的编号呢?在矩阵的表示中可以发现第$i$行恰好有$i$个格子,因此如果知道当前$x$号格子的坐标为$(i,j)$,那么上面两个的坐标就是$(i-1,j)$和$(i-1,j-1)$,要减去的格子坐标是$(i-2,j-1)$。而已知坐标推格子编号还是很容易的,有公式$g(i,j) = \sum\limits_{k=1}^{i-1}{k}+j = \dfrac{i \cdot (i-1)}{2}+j$,因此递推公式就变成了$$f(g(i,j)) = {g^2}(i,j) + f(g(i-1,j)) + f(g(i-1,j-1)) - f(g(i-2,j-1))$$

  可以发现每次用到的都是上一行的结果,因此我们可以从第$2$行开始往下递推(其中$f(1)=1$)。然后可能往上走有些格子并不存在,此时公式就有所变化了,如果对应的格子不存在那么直接不考虑该项结果即可,对应的细节处理见代码。

  我们直接预处理出来$10^6$以内的$f(x)$,询问的时候直接查表,因此计算量为$O(10^6 + T)$。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 1e6 + 10;
 7 
 8 LL f[N];
 9 
10 void init() {
11     f[1] = 1;   // 边界情况f(1)=1
12     for (int i = 2, k = 2; k < N; i++) {    // 从第2行开始枚举,k是要枚举的格子编号
13         for (int j = 1; j <= i; j++, k++) { // 第i行最多有i列,即纵坐标不超过横坐标
14             f[k] = 1ll * k * k;
15             if (i - 1 > 0) {    // 上一行(第i-1行)存在
16                 if (j <= i - 1) f[k] += f[(i - 2) * (i - 1) / 2 + j];   // 列不超过行,存在格子(i-1,j)
17                 if (j - 1 > 0) {    // 首先必然有j-1 <= i-1,然后还要保证j-1 > 0,没有越界,才存在格子(i-1,j-1)
18                     f[k] += f[(i - 2) * (i - 1) / 2 + j - 1];
19                     if (i - 2 > 0 && j - 1 <= i - 2) f[k] -= f[(i - 3) * (i - 2) / 2 + j - 1];  // 第i-2行存在且列不超过行(已经保证j-1 > 0了)
20                 }
21             }
22         }
23     }
24 }
25 
26 void solve() {
27     int n;
28     scanf("%d", &n);
29     printf("%lld\n", f[n]);
30 }
31 
32 int main() {
33     init();
34     int t;
35     scanf("%d", &t);
36     while (t--) {
37         solve();
38     }
39     
40     return 0;
41 }

 

参考资料

  Codeforces Round 871 (Div. 4) A - H:https://zhuanlan.zhihu.com/p/627396904

posted @ 2023-05-08 14:48  onlyblues  阅读(80)  评论(0编辑  收藏  举报
Web Analytics