ZOJ 3224(数学+暴力)

来源:互联网 发布:python pyqt5 安装 编辑:程序博客网 时间:2024/06/06 08:40

感谢 @dhk@mzx

n的范围很大直接判断的肯定T;考虑划分,虽然n的取值范围很大,但是logai(n)的最大值为30,所以对于A~B最多划分成n*30个区间,每个区间内部每个数对应的的[logai(n)]都是

相等的,直接计算个数就可以;这个区间内的合法的整数的个数就是能整除LCM{ [ logai(n) ] } 的数的个数;

取对数可能会丢精度。。。第一次知道;

#include <bits/stdc++.h>using namespace std;const int N = 505;const double EPS = 1e-9;long long a[N],ary[N*31],n,l,r,ma,co;long long gcd(long long a, long long b){    return b == 0 ? a : gcd(b, a % b);}long long Count(long long a, long long b,long long d){    b = b / d * d;    a = (a - 1) / d * d;    return (b - a) / d;}int main(){    while(~scanf("%lld%lld%lld",&n,&l,&r))    {        ma = 0;        for(int i = 0 ; i < n ; i++)        {            scanf("%lld",&a[i]);            ma = max(ma,a[i]);        }        co = 0;        ma = max(ma,l);        ary[co++] = ma;        for(int i = 0 ; i < n ; i++)        {            long long tem = 1;            while(tem * a[i] <= r)            {                tem *= a[i];                if(tem <= ma) continue;                ary[co++] = tem;            }        }        sort(ary,ary+co);        co = unique(ary,ary+co) - ary;        ary[co] = r+1;        long long ans = 0;        for(int i = 0 ; i < co ; i++)        {            long long d = 1;            for(int j = 0 ; j < n ; j++)            {                long long tem = ( log(ary[i]*1.0)/log(a[j]*1.0) ) + EPS;                d = d / gcd(d,tem) * tem;                if(d > r) break;            }            ans += Count(ary[i], ary[i+1] - 1, d);        }        printf("%lld\n",ans);    }}