多校 GCD

Give you a sequence of  N(N100,000)  integers :  a1,...,an(0<ai1000,000,000) . There are  Q(Q100,000)  queries. For each query  l,r  you have to calculate  gcd(al,,al+1,...,ar)  and count the number of pairs (l,r)(1l<rN) 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<ai1000,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) .  
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

我们注意观察

gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar) ,当l固定不动的时候, r=l...nr=l...n 时,我们可以容易的发现,随着 rr 的増大, gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar) 是递减的,同时 gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar) 最多 有 log\ 1000,000,000log 1000,000,000 个不同的值,为什么呢?因为 a_{l}al 最多也就有 log\ 1000,000,000log 1000,000,000 个质因数

所以我们可以在log级别的时间处理出所有的以L开头的左区间的gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar) 那么我们就可以在n\ log\ 1000,000,000n log 1000,000,000的时间内预处理出所有的gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)然后我们可以用一个map来记录,gcd值为key的有多少个 然后我们就可以对于每个询问只需要查询对应gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)为多少,然后再在map 里面查找对应答案即可.

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define LL long long

using namespace std;
int a[110000];
//pair.first为求的GCD
//pair.second为区间的R
//vec对应的下标为区间的L
vector >vec[110000];
mapM;
int main()
{
    int T,t=0;
    int l,r;
    int n,m;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i = 1; i <= n; ++i){
            scanf("%d",&a[i]);
            vec[i].clear();
        }

        M.clear();
        for(int i = n; i >= 1; i--){
            int g = 0;
            /*
            L+1....R3...R2....R1....R0
            L+1....R3区间的GCD相同
            L+1....R3+1和L...R3+2和...和L+1....R2的GCD相同
            L+1....R2+1和L...R2+2和...和L+1....R1的GCD相同
            L+1....R1+1和L...R1+2和...和L+1....R0的GCD相同
            假设L+k



你可能感兴趣的:(acm)