TSOJ--2018 江苏省省赛

[2018 江苏省大学生程序设计大赛]

K. 2018 (测试数据范围有扩大)

Problem

Given a, b, c, d, find out the number of pairs of integers (x, y) where a ≤ x ≤ b, c ≤ y ≤ d and x·y is a multiple of 2018.

Input

The input consists of several test cases and is terminated by end-of-file.

Each test case contains four integers a, b, c, d.

Output

For each test case, print an integer which denotes the result.

Constraint

• Qing Jiang felt that the original edition of the test cases is too easy, so he enlarged the scope of data. The current edition is:

• 1 ≤ a ≤ b ≤ 2³¹ - 1, 1 ≤ c ≤ d ≤ 2³¹ - 1

• The number of tests cases is around at 1·10⁵.

Sample Input

1 2 1 2018

1 2018 1 2018

1 1000000000 1 1000000000

Sample Output

3

6051

1485883320325200

Constraint of original edition (省赛原题测试数据规模,非 TSOJ 此题的数据规模,下列数据 仅供参考 )

• 1 ≤ a ≤ b ≤ 10⁹, 1 ≤ c ≤ d ≤ 10⁹

• The number of tests cases does not exceed 10⁴.

 

 

题目大意: 在a,b区间和c,d区间内找一些数使得这些数的乘积是2018的倍数

题解   :   找2018的约数,有1,2,1009,2018这四个数,然后找它们的数量

#include<iostream>
#include<cstdio>
using namespace std;
long long Count(int n,int m) //用来求区间中2的倍数的个数
{
    if(n%2==0&&m%2==0)
        return ((m-n)/2+1);
    else if(n%2!=0&&m%2!=0)
        return ((m-n)/2);
    else
        return ((m-n+1)/2);
}
int main()
{
    int a,b,c,d;
    long long ans,f1,f2;
    while(scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF)
    {
        ans=0;
        f1=Count(a,b);
        f2=Count(c,d);
        long long a18=d/2018-(c-1)/2018;//区间中2018的倍数的个数
            ans+=a18*(b-a+1);  
        long long a19=d/1009-(c-1)/1009-a18;  //区间中1009的倍数的个数
            ans+=a19*f1;
            
        long long a28=b/2018-(a-1)/2018;
            ans+=a28*(d-c+1);
        long long a29=b/1009-(a-1)/1009-a28;
            ans+=a29*f2;
        
        printf("%lld
",ans-(a29*a18+a28*(a19+a18)));//最后要减去多乘的数
    }
    return 0;
}

 

     

原文地址:https://www.cnblogs.com/acmblog/p/9540668.html