GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
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.
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).
/*
RMQ-ST算法 + 二分預處理
查詢次數太多,不能直接二分查詢
因爲GCD其實最多隻有nlog2(n)種 所以可以先預處理在map中
*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <bitset>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define inf 0x7fffffff
#define maxn 100010
using namespace std;
int gcd[23][maxn*2];
int a[maxn];
long long ans;
int n, q;
void ST(int num)
{
for (int i = 1; i <= num; i++)
{
gcd[0][i] = a[i];
}
for (int i = 1; i <= log2(num); i++)
for (int j = 1; j <= num; j++)
if (j + (1 << i) - 1 <= num)
{
int a = gcd[i - 1][j], b = gcd[i - 1][j + (1 << i >> 1)];
gcd[i][j]=__gcd(a,b);
}
}
int RMQ(int x, int y)
{
int k = (int) log2(y - x + 1.0);
int a = gcd[k][x], b = gcd[k][y - (1 << k) + 1];
return __gcd(a,b);
}
int main()
{
int T;
scanf("%d", &T);
for(int tt=1;tt<=T;tt++)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
ST(n);
scanf("%d",&q);
printf("Case #%d:\n",tt);
map<int,long long> mp;
for(int i=1;i<=n;i++)
{
int g=gcd[0][i],j=i;
while(j<=n)
{
int left = j, right = n, mid;
while (left <= right)
{
mid = (left + right) / 2;
if (RMQ(i, mid) >= g)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
mid=(left+right)/2;
mp[g]+=(mid-j+1);
j=mid+1;
g=RMQ(i,j);
}
}
while(q--)
{
int a,b;
scanf("%d %d",&a,&b);
int ans=RMQ(a,b);
printf("%d %I64d\n",ans,mp[ans]);
}
}
return 0;
}