HDU 5726 GCD

题意:动态查询区间的gcd,和gcd的值的个数。

分析:gcd的查找可以线段树,val(node) = gcd(val(left),val(val)),我是用ST表搞的。

然后查询这个值的区间有多少个。

简单说就是,这个gcd 不会很多,可以分区间hash好。

二分写的很糟。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100000+5;

int n;
int a[maxn];
int d[maxn][20];

int gcd(int a,int b)
{
    return b==0 ? a : gcd(b,a%b);
}

void init(int* a)
{
    for(int i=0; i<n; i++)
        d[i][0] = a[i];
    for(int j=1; (1<<j)<=n; j++)
        for(int i=0; i+(1<<j)-1<n; i++)
            d[i][j] = gcd(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}

int sol(int L,int R)
{
    int k = 0;
    while(1<<(k+1)<=R-L+1) k++;
    return gcd(d[L][k],d[R-(1<<k)+1][k]);
}

int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    int kase = 1;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);

        init(a);

        map<int,long long> rec;
        for(int i=0; i<n; i++)
        {
            int g = d[i][0],L=i;

            while(L<n)
            {
                int l = L;
                int r = n;
                g = sol(i,L);
                while(l<r)
                {
                    if(r-l==1) {
                        if(sol(i,r)==g&&r!=n) {
                            l = r;
                            break;
                        }
                        else break;
                    }
                    int mid = l+(r-l)/2;

                    int tmp = sol(i,mid);

                    if(tmp==g)
                        l = mid;
                    else r = mid-1;
                }
                //printf("%d %d
",l,l-L+1);
                rec[g] += (l-L)+1;
                L = l+1;
            }
        }

        printf("Case #%d:
",kase++);

        int q;
        scanf("%d",&q);
        while(q--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            l--;
            r--;
            int tmp = sol(l,r);
            printf("%d %I64d
",tmp,rec[tmp]);

        }

    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/7230771.html