GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)total Submission(s): 877 Accepted Submission(s): 266
Problem Description
Give you a sequence of
N(N≤100,000)
integers :
a1,...,an(0<ai≤1000,000,000)
. There are
Q(Q≤100,000)
queries. For each query
l,r
you have to calculate
gcd(al,,al+1,...,ar)
and count the number of pairs
(l′,r′)(1≤l<r≤N)
such that
gcd(al′,al′+1,...,ar′)
equal
gcd(al,al+1,...,ar)
.
Input
The first line of input contains a number
T
, which stands for the number of test cases you need to solve.
The first line of each case contains a number N , denoting the number of integers.
The second line contains N integers, a1,...,an(0<ai≤1000,000,000) .
The third line contains a number Q , denoting the number of queries.
For the next Q lines, i-th line contains two number , stand for the li,ri , stand for the i-th queries.
The first line of each case contains a number N , denoting the number of integers.
The second line contains N integers, a1,...,an(0<ai≤1000,000,000) .
The third line contains a number Q , denoting the number of queries.
For the next Q lines, i-th line contains two number , stand for the li,ri , stand for the i-th queries.
Output
For each case, you need to output “Case #:t” at the beginning.(with quotes,
t
means the number of the test case, begin from 1).
For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs (l′,r′) such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar) .
For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs (l′,r′) such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar) .
Sample Input
1 5 1 2 4 6 7 4 1 5 2 4 3 4 4 4
Sample Output
Case #1: 1 8 2 4 2 4 6 1
先用ST算法求出区间公约数.在打表求出公约数为i有多少个.用map m1记录以i为区间右端点时各个最大公约数有多少个,再用m2记录以i+1为区间右端点时每个公约数有多少个,因为m1已经计算出,在计算m2时,遍历m1的公约数,和num[i+1]求最大公约数,并记录在m2中。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#define maxn 100005
#define INF 1000000000
using namespace std;
typedef long long ll;
ll dp[maxn][20], n, num[maxn];
map<ll, ll> m1, m2, ans;
ll gcd(ll a, ll b){
return b ? gcd(b, a % b) : a;
}
void ST(){
scanf("%I64d", &n);
for(int i = 0; i < n; i++){
scanf("%I64d", &num[i]);
dp[i][0] = num[i];
}
for(int i = 1; (1<<i) <= n; i++)
for(int j = 0; j+(1<<i) <= n; j++)
dp[j][i] = gcd(dp[j][i-1], dp[j+(1<<(i-1))][i-1]);
}
int main(){
// freopen("in.txt", "r", stdin);
int t, cas = 0;
scanf("%d", &t);
while(t--){
ST();
m1.clear();
m2.clear();
ans.clear();
m1[num[0]]++;
ans[num[0]]++;
for(int i = 1; i < n; i++){
m2[num[i]]++;
ans[num[i]]++;
map<ll, ll> ::iterator iter = m1.begin();
for(; iter != m1.end(); iter++){
int c = gcd(iter -> first, num[i]);
m2[c] += iter -> second;
ans[c] += iter -> second;
}
m1 = m2;
m2.clear();
}
int q;
scanf("%d", &q);
printf("Case #%d:\n", ++cas);
while(q--){
int l, r;
scanf("%d%d", &l, &r);
l--;
r--;
int k = 0;
while(1<<(k+1) <= r - l + 1)
k++;
ll d = gcd(dp[l][k], dp[r-(1<<k)+1][k]);
printf("%I64d %I64d\n", d, ans[d]);
}
}
return 0;
}