HDU 5726 GCD

GCD


Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)



Problem Description
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

 直接RMQ預處理+二分查找T了。因爲查詢次數太多,其實gcd種類數目不多,所以可以先預處理開個map記錄gcd爲某個值的數目。
先for循環遍歷區間起點,然後二分查找每次區間gcd變化時的終點,存到map中。
/*
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;
}


發佈了58 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章