【ACM-2017四川省賽】G . 2017

題目描述

G. 2017

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 multiple of 2017.

Input

The input contains zero or more test cases and is terminated by end-of-file.
Each test case contains four integers a, b, c, d.
• 1 ≤ a ≤ b ≤ 109 , 1 ≤ c ≤ d ≤ 109
• The number of tests cases does not exceed 104

Output

For each case, output an integer which denotes the result.

Sample Input

1 2017 1 2016
1 1000000000 1 1000000000

Sample Output

2016
991324197233775

題意分析

從題目描述中可以很輕易的讀懂(英語渣 _ ),就是給定區間 [ a , b ] , [ c , d ] , 然後分別在兩個區間中各找一個數 x , y , 要求 x 屬於第一個區間, y 屬於第二個區間,並且 x * y 是2017的倍數。

拿到這道題目的時候其實我是很開心的,畢竟分析了下就有了思路(畢竟大家都說是水題噠)

解題分析

首先,2017是一個素數,那麼要想 x * y 是2017的倍數,x , y 必定存在至少一個數是2017的倍數

當選定了一個數,假定是 x , 那麼 y 無論何值都滿足條件(注意 a b c d 的範圍都是1 到1e9)

對於一個區間中,找出2017的倍數,第一種方法是篩法求,其實這種方法效率已經很高了。不過還有更爲高效的方法:就 [ a , b ] 區間來說,令 m = b/2017, n = a/2017 , 很顯然,m - n在大多數情況下就能直接得到此區間中2017的倍數有多少個,但是注意,當 a 也是2017的倍數的時候,應爲 m - n + 1 (此點也是一直卡住我的地方,當時想到了會多一個,但是在判斷是否 +1 的這個條件的時候,誤以爲是隻要 a/2017不爲0時則加1,從而導致WA,心累呀)

由上邊得到了 m 和 n 後,我們能夠得到 m*len2(第二個區間的長度),n*len1(第一個區間的長度)之和則爲所有的可能數,但是在這樣的情況下,我們會發現我們有可能會存在多加的情況,當兩個區間有交集並且交集中存在2017的倍數的情況下,此時我們會多加一定的可能數,那麼我們如何去解決這種情況呢?

第一種方法:既然我們已經算出了 m*len2 + n*len1, 那麼我們只需要減去對應的重複項即可,即查找出兩個區間中重複的2017的倍數項的個數 x,那麼結果即爲 res = m*len2 + n*len1 - x*x
第二種方法:我們逆向思考,我們需要的是符合條件的,那麼是不是總數 - 不符合條件數即可呢?我們想下,題目中的總數即爲len1 * len2 , 不符合條件的即爲 (len1 - m) * (len2 - n) ,那麼結果 res = len1 * len2 - (len1 - m) * (len2 - n)

AC代碼

#include <bits/stdc++.h>
using namespace std;
int main(){
    long long a,b,c,d;
    while(cin>>a>>b>>c>>d){
        long long len1 = b-a+1;
        long long len2 = d-c+1;
        long long m= 0 ,n=0;
        m = b/2017 - a/2017;
        if(a%2017 == 0){
            m++;
        }
        n = d/2017 - c/2017;
        if(c%2017 == 0){
            n++;
        }
        unsigned long long res = 0;
        res = len1*len2 - (len1-m)*(len2-n);
        cout<<res<<endl;
    }
    return 0;
}

注:

如有錯誤,歡迎dalao評論指正
.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章