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)
.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args){
new Task().solve() ;
}
}
class Task{
InputReader in = new InputReader(System.in) ;
PrintWriter out = new PrintWriter(System.out) ;
int[] num , gcd ;
int n ;
int _gcd(int x , int y){
return y == 0 ? x : _gcd(y, x%y) ;
}
void build(int l , int r , int t){
if(l == r){
gcd[t] = num[l] ;
return ;
}
int mid = (l + r) >> 1 ;
build(l, mid, t<<1) ;
build(mid+1 , r , t<<1|1) ;
gcd[t] = _gcd(gcd[t<<1] , gcd[t<<1|1]) ;
}
int query(int L , int R , int l , int r , int t){
if(L <= l && r <= R) return gcd[t] ;
int res = 0 ;
int mid = (l + r) >> 1 ;
if(L <= mid) res = _gcd(res , query(L, R, l, mid, t<<1)) ;
if(R > mid) res = _gcd(res, query(L, R, mid+1, r, t<<1|1)) ;
return res ;
}
Map<Integer , Long>[] mapper = new HashMap[2];
Map<Integer , Long> result = new HashMap<Integer , Long>() ;
int t ;
void init(){
mapper[0] = new HashMap<Integer, Long>() ;
mapper[1] = new HashMap<Integer, Long>() ;
mapper[0].put(num[1] , 1L) ;
t = 0 ;
result.clear();
result.putAll(mapper[0]) ;
for(int i = 2 ; i <= n ; i++){
mapper[t^1].clear() ;
mapper[t^1].put(num[i] , 1L) ;
for(Map.Entry<Integer, Long> entry : mapper[t].entrySet()){
int gcd = _gcd(entry.getKey() , num[i]) ;
long cnt = entry.getValue() ;
Long size = mapper[t^1].get(gcd) ;
mapper[t^1].put(gcd , cnt + (size == null ? 0L : size));
}
for(Map.Entry<Integer, Long> entry : mapper[t^1].entrySet()){
long cnt = entry.getValue() ;
Long size = result.get(entry.getKey()) ;
result.put(entry.getKey() , cnt + (size == null ? 0L : size));
}
t ^= 1 ;
}
}
void solve(){
int t = in.nextInt() ;
for(int cas = 1 ; cas <= t ; cas++){
n = in.nextInt() ;
num = new int[n+1] ;
gcd = new int[n<<2] ;
for(int i = 1 ; i <= n ; i++) num[i] = in.nextInt() ;
init();
build(1 , n , 1) ;
int m = in.nextInt() ;
out.println("Case #" + cas + ":") ;
while(m-- > 0){
int gcd = query(in.nextInt() , in.nextInt() , 1 , n , 1) ;
Long cnt = result.get(gcd) ;
out.println(gcd + " " + (cnt == null ? 0L : cnt)) ;
}
//out.flush();
}
out.flush();
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = new StringTokenizer("");
}
private void eat(String s) {
tokenizer = new StringTokenizer(s);
}
public String nextLine() {
try {
return reader.readLine();
} catch (Exception e) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String s = nextLine();
if (s == null)
return false;
eat(s);
}
return true;
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
}