gym/101810-N-Dimensional Grid【找规律】

N-Dimensional Grid

You are given an n-dimensional grid in which the dimensions of the grid are a1 × a2 × … × an. Each cell in the grid is represented as an n-tuple (x1, x2, …, xn) (1 ≤ xi ≤ ai).

Two cells are considered to be adjacent if the Manhattan Distance between them is equal to 1. The Manhattan Distance between two cells X(x1, x2, …, xn) and Y(y1, y2, …, yn) is equal to: |x1 - y1| + |x2 - y2| + … + |xn - yn|.

Your task is to count how many pairs of cells are adjacents. Can you? Two pairs of cells are considered the same if they include the same cells, i.e the pair (c1, c2) is the same as (c2, c1).

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 105), in which n is the number of dimensions of the grid. Then a line follows containing n integers a1, …, an (1 ≤ ai ≤ 105), in which ai is the size of the ith dimension.

The sum of n overall test cases does not exceed 6 × 106.

Output

For each test case, print a single line containing the number of pairs of adjacent cells modulo 109 + 7.

Example

Input

1
3
1 2 3

Output

7


题意:

在一个 n n 维空间中的一个点可以表示为一个n元组 (a1,a2,a3,a4,a5,...,an) ( a 1 , a 2 , a 3 , a 4 , a 5 , . . . , a n )
两个格子相邻时:这两个格子的曼哈顿距离为1,即对于两个点 X(x1,x2,...,xn) X ( x 1 ,   x 2 ,   . . . ,   x n ) Y(y1,y2,...,yn) Y ( y 1 ,   y 2 ,   . . . ,   y n ) |x1y1|+|x2y2|+...+|xnyn|. | x 1   −   y 1 |   +   | x 2   −   y 2 |   +   . . .   +   | x n   −   y n | .
在给出每个维度的size后,求这个空间中有多少对相邻的格子。

.
.
.
.
.
.
.
.
.

解:

从一维开始,n个格子有n-1对相邻。
现在的答案为ans[1],现在一共有num[1]个格子

当多增加一维时,若这一维的size为m(就有m个前一维),则当前一共有 ans[1]×m a n s [ 1 ] × m 个与前一维一样的(前一维复制m遍)
然后每一个维与维维之间有 (m1)×num[1] ( m − 1 ) × n u m [ 1 ]
所以新的答案ans[2]是 ans[2]×m+(m1)×num[1] a n s [ 2 ] × m + ( m − 1 ) × n u m [ 1 ]
然后当前一共有 n×m n × m 个格子,num[2]=n*m

再加一维size为k的:
ans[3]=ans[2]*k+(k-1)*num[2]

推广这个规律,

ans[i]=ans[i1]×a[i]+num[i1]×a[i]1 a n s [ i ] = a n s [ i − 1 ] × a [ i ] + n u m [ i − 1 ] × a [ i ] − 1

typedef long long ll;
ll ans;
const ll MOD = 1000000000 + 7;
int a[100000 + 10];
int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        memset(a,0, sizeof(a));
        int n;
        ans = 0;
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        ll num = a[0];
        ans = a[0] - 1;//第一维
        for (int i = 1; i < n; i++)
        {
            ans = ans * a[i];
            ans %= MOD;
            ans = ans + (a[i] - 1)*num;
            num *= a[i];
            num %= MOD;
            ans %= MOD;
        }
        printf("%lld\n", ans);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值