思路题 和 gcd (最大公约数) 与 lcm (最小公倍数)

In this problem, subarray is defined as non-empty sequence of consecutive elements.

We define a subarray as Super Subarray if the summation of all elements in the subarray is divisible by each element in it.

Given an array a of size n, print the number of Super Subarrays in a.

Input

The first line of the input contains a single integer T (1 ≤ T ≤ 100), the number of test cases.

The first line of each test case contains one integer n (1 ≤ n ≤ 2000), the length of array a.

The second line of each test case contains the sequence of elements of the array a1, a2, ..., an (1 ≤ ai ≤ 109), ai is the i-th element of the array a.

Output

For each test case, print a single integer that represents the number of Super Subarrays in a, on a single line.

Example
Input
2
5
1 2 3 4 5
5
2 3 4 3 6
Output
6

6

题目翻译过来的意思是 :

给定t 测试次数

n 数组长度,下面n个数字,在1到1e9中。

求连续的子序列中,其的和能被所有的数字整除 的个数。

比如 样例中

5

1 2 3 4 5

输出的是6, 是存在(1,2,3) (1) (2) (3) (4) (5) 所以是6次。

ac代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define Swap(a,b,t) a=t,a=b,b=t
using namespace std;
typedef unsigned long long ll;//用LL 过不去,,,下次用 typedef unsigned long long ll; 卡了两个小时 
const int MA=2005;
ll a[MA],sum[MA],lcmm;
ll gcd(ll m,ll n)  //欧几里得算法求最大公约数,也算辗转相除。 
{
return (m==0)?n:gcd(n%m,m);
}
ll lcm(int a,int b)
{
return a/gcd(a,b)*b;//求最小公倍数 , a和b的最小公倍数= a*b/(a和b的最大公约数)
}
int main()
{
int T;
cin>>T;
while (T--){
// memset(sum,0,sizeof(sum));
int n,i,j,ans=0;
scanf("%d",&n);//cin>>n;   
for (i=1;i<=n;i++){
scanf("%lld",&a[i]);//cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
for (i=1;i<=n;i++){ //i为数组左节点 
lcmm=a[i];
for (j=i+1;j<=n;j++){ //j为数组右节点 
lcmm=lcmm/gcd(lcmm,a[j])*a[j];
if ((sum[j]-sum[i-1])%lcmm==0) ans++;
if (lcmm>(sum[n]-sum[i-1])) break;
}

printf("%d\n",ans+n);//cout<<ans<<endl;
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/a1204675546/article/details/80586174