zoukankan      html  css  js  c++  java
  • 【CODEFORCES】 D. CGCDSSQ

    D. CGCDSSQ
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Given a sequence of integers a1, ..., an and q queries x1, ..., xq on it. For each query xi you have to count the number of pairs (l, r)such that 1 ≤ l ≤ r ≤ n and gcd(al, al + 1, ..., ar) = xi.

     is a greatest common divisor of v1, v2, ..., vn, that is equal to a largest positive integer that divides all vi.

    Input

    The first line of the input contains integer n, (1 ≤ n ≤ 105), denoting the length of the sequence. The next line contains n space separated integers a1, ..., an, (1 ≤ ai ≤ 109).

    The third line of the input contains integer q, (1 ≤ q ≤ 3 × 105), denoting the number of queries. Then follows q lines, each contain an integer xi, (1 ≤ xi ≤ 109).

    Output

    For each query print the result in a separate line.

    Sample test(s)
    input
    3
    2 6 3
    5
    1
    2
    3
    4
    6
    
    output
    1
    2
    2
    0
    1
    
    input
    7
    10 20 3 15 1000 60 16
    10
    1
    2
    3
    4
    5
    6
    10
    20
    60
    1000
    
    output
    14
    0
    2
    2
    2
    0
    2
    2
    1
    1
    题解:题目大意是说给你一个序列,然后有q个询问,每一个询问描写叙述成一个正整数c。问你在这个序列中,区间上的最大公约数等于c的区间共同拥有多少个。

    由于我们仅仅关心个数而并不关心区间。所以能够递推来写。如果我们知道了第以i个数为结尾的全部区间上的最大公约数。我们就能够统计他的个数。而我们在讨论i+1的时候,我们是能够推出以第i+1个数结尾的全部最大公约数的(和第i个数的结果依次取GCD即可)。然后统计个数(事实上就是直接加进去)。最后记得每次把第i个数的结果加到ANS里面即可了。

    代码并不长,时间也不长。果然是由于map太快了么= =||

    #include <iostream>
    #include <cstring>
    #include <map>
    #include <cstdio>
    
    using namespace std;
    
    int a[100005],n,q,c;
    
    int gcd(int a,int b)
    {
        if (!b) return a;
        else return gcd(b,a%b);
    }
    
    map<int,long long> ans;
    map<int,int> last;
    map<int,int> now;
    map<int,int>::iterator itr;
    
    int main()
    {
        scanf("%d",&n);
        for (int i=0;i<n;i++) scanf("%d",&a[i]);
        ans.clear();
        for (int i=0;i<n;i++)
        {
            swap(last,now);
            now.clear();
            for (itr=last.begin();itr!=last.end();itr++)
                now[gcd(itr->first,a[i])]+=itr->second;
            now[a[i]]++;
            for (itr=now.begin();itr!=now.end();itr++)
                ans[itr->first]+=itr->second;
        }
        scanf("%d",&q);
        for (int i=0;i<q;i++)
        {
            scanf("%d",&c);
            printf("%I64d
    ",ans[c]);
        }
        return 0;
    }
    

  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6905925.html
Copyright © 2011-2022 走看看