B. GCD Partition

B. GCD Partition

While at Kira's house, Josuke saw a piece of paper on the table with a task written on it.

The task sounded as follows. There is an array a of length n. On this array, do the following:

  • select an integer k>1;
  • split the array into k subsegments ;
  • calculate the sum in each of k subsegments and write these sums to another array b (where the sum of the subsegment (l,r) is j=lraj);
  • the final score of such a split will be gcd(b1,b2,,bk).

The task is to find such a partition that the score is maximum possible. Josuke is interested in this task but is not strong in computer science. Help him to find the maximum possible score.

A division of an array into k subsegments is k pairs of numbers (l1,r1),(l2,r2),,(lk,rk) such that liri and for every 1jk1 lj+1=rj+1, also l1=1 and rk=n. These pairs represent the subsegments.

gcd(b1,b2,,bk) stands for the greatest common divisor (GCD) of the array b.

Input

The first line contains a single number t (1t104) — the number of test cases.

For each test case, the first line contains one integer n (2n2105) — the length of the array a.

The second line contains n integers a1,a2,a3,,an (1ai109) — the array a itself.

It is guaranteed that the sum of n over all test cases does not exceed 2105.

Output

For each test case print a single integer — the maximum score for the optimal partition.

Example

input

复制代码
6
4
2 2 1 3
2
1 2
3
1 4 5
6
1 2 1 1 1 3
10
12 30 37 88 12 78 89 17 2 12
6
7 7 7 7 7 7
复制代码

output

4
1
5
3
1
21

Note

In the first test case, you can choose k=2 and split the array into subsegments (1,2) and (3,4).

Then the score of such a partition will be equal to gcd(a1+a2,a3+a4)=gcd(2+2,1+3)=gcd(4,4)=4.

In the fourth test case, you can choose k=3 and split the array into subsegments (1,2),(3,5),(6,6).

The split score is gcd(1+2,1+1+1,3)=3.

 

解题思路

  可以证明最优解必定出现在将序列分成两段的情况中。

  假如将序列分成m>2段,那么此时的答案是gcd(b1,b2,,bm),有gcd(b1,b2,,bm)gcd(b1+b2,b3,,bm),这是因为对于b1,,bm的任意一个公约数d,都一定能整除b1+b2,b3,,bm,即也是b1+b2,b3,,bm的公约数。因此就有gcd(b1,b2,,bm)gcd(b1+b2,b3,,bm)。以此类推,为了得到最大值最终一定会变成gcd(b1,b2)的形式。因此可以枚举两段的分界点来求最大值。

  补充另外一个方法证明gcd(a,b,c)gcd(a+b,c)。设a=px, b=py, c=pz,那么a+b=p(x+y)gcd(a,b,c)=gcd(px,py,pz)=pgcd(a+b,c)=gcd(p(x+y),pz)=pgcd((x+y),z)p=gcd(a,b,c)

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 LL s[N];
 9 
10 LL gcd(LL a, LL b) {
11     return b ? gcd(b, a % b) : a;
12 }
13 
14 void solve() {
15     int n;
16     scanf("%d", &n);
17     for (int i = 1; i <= n; i++) {
18         // 因为写成scanf("%d", s + i)被hack了,由于有多组测试数据,因此要保证s[i]的64位均为0
19         scanf("%lld", s + i);
20         s[i] += s[i - 1];
21     }
22     LL ret = 1;
23     for (int i = 1; i < n; i++) {
24         ret = max(ret, gcd(s[i], s[n] - s[i]));
25     }
26     printf("%lld\n", ret);
27 }
28 
29 int main() {
30     int t;
31     scanf("%d", &t);
32     while (t--) {
33         solve();
34     }
35     
36     return 0;
37 }
复制代码

 

参考资料

  Codeforces Round #846 (Div. 2) — Tutorial:https://codeforces.com/blog/entry/111841

  CF1708B-solution:https://www.luogu.com.cn/blog/NK-TBW2765/cf1708b-solution

posted @   onlyblues  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示