传送门: http://acm.hdu.edu.cn/showproblem.php?pid=5726
GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 4341 Accepted Submission(s): 1550
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
Author
HIT
Source
123
题意 : 给 n 个数 m 次查询 问 从 a-b GCD是多少 并且问 你 在 整个n区间内 GCD = GCD(a,b)的 有多少个;
10w 的数据 QMR查询 利用ST 动态 打表, 求GCD
二分从 1-n 存取 GCD的相等的数目:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define S1(n) scanf("%d",&n)
#define SL1(n) scanf("%I64d",&n)
#define S2(n,m) scanf("%d%d",&n,&m)
#define SL2(n,m) scanf("%I64d%I64d",&n,&m)
#define Pr(n) printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e5+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
int n;
ll a[maxn];
ll maps[maxn][25];
void ST()
{
for(int i=1;i<=n;i++)
maps[i][0]=a[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
maps[i][j]=gcd(maps[i][j-1],maps[i+(1<<j-1)][j-1]);
}
ll get_gcd(int l,int r)
{
if(l>r)swap(l,r);
int x= int (log(r-l+1)/log(2));
return gcd(maps[l][x],maps[r-(1<<x)+1][x]);
}
int main()
{
int T;
S1(T);
int cont=0;
while(T--)
{
S1(n);
mem(a,0);
mem(maps,0);
for(int i=1;i<=n;i++)
S1(a[i]);
map<ll,ll>mp;
ST();
for(int i=1;i<=n;i++)
{
ll val= a[i];
int pos =i;
while(pos<=n)
{
//cout<<"pos "<<pos<<endl;
int l=pos;
int r=n;
val=get_gcd(i,pos);
while(r>l)
{
int mid=(l+r+1)>>1;
if(get_gcd(i,mid)==val)
l=mid;
else
r=mid-1;
}
mp[val]+=(l-pos)+1;
pos=l+1;
}
}
int m;
printf("Case #%d:\n",++cont);
cin>>m;
int x,y;
while(m--)
{
scanf("%d %d",&x,&y);
ll ans=get_gcd(x,y);
printf("%lld %lld\n",ans,mp[ans]);
}
}
return 0;
}