C题解
简单的公式
https://ac.nowcoder.com/acm/contest/9247/A
观察得2021为43和47的倍数
首先写出43倍数,47倍数,2021倍数个数的函数,和其区间中包含个数的函数
我是如下图写的
long long S1(long long x){ return x/43; } long long S2(long long x){ return x/47; } long long S3(long long x){ return x/2021; } long long s1(long long l,long long r){ return S1(r)-S1(l-1); } long long s2(long long l,long long r){ return S2(r)-S2(l-1); } long long s3(long long l,long long r){ return S3(r)-S3(l-1); }
当然也可以写成这样,S(l,r,k)代表区间k倍数的数个数
long long S(long long l,long long r,long long k){ return r/k-(l-1)/k; }
接下来利用就是求对数,对数分为四种
①[a,b]取2021倍数,[c,d]可以取任意值
②[c,d]取2021倍数,[a,b]可以取任意值
③[a,b]为43的倍数,[c,d]为47的倍数
④[a,b]为47的倍数,[c,d]为43的倍数
注意①和②有重复,也就是[a,b],[c,d]都为2021的倍数时,所以要减去
long long findPairs(long long a, long long b, long long c, long long d) { long long ans=0; ans+=s3(a,b)*(d-c+1)+s3(c,d)*(b-a+1)-s3(a,b)*s3(c,d); ans+=(s1(a,b)-s3(a,b))*(s2(c,d)-s3(c,d)); ans+=(s2(a,b)-s3(a,b))*(s1(c,d)-s3(c,d)); return ans; }