题意:给定a,b,c,d。问有多少对a<=x<=b , c<=y<=d x*y是2018的倍数
思路:2018只有四个因子,1,2, 1009, 2018
答案分为四个部分
1、x是2018的倍数有r1对 。r1指[c,d]之间有多少个1的倍数
2、x是1009的倍数(此处排除2018的倍数) 有reven对。 reven指[c,d]之间有多少个2的倍数
3、x是2的倍数(此处排除2018的倍数)有r1009对 。r1009指[c,d]之间有多少个1009的倍数
4、x是1 (此处减去2的倍数、减去1009的倍数、加上2018的倍数)。有r2018对 指[c,d]之间有多少个2018的倍数
所以只需要计算在区间里有多少个倍数
LL calc(int a,int b,int x) //计算区间a,b里有多少个x的倍数
{
int left=a/x;
int right=b/x;
LL ans=right-left;
if(a%x==0) ans+=1; //若左边界为x的整数倍,需要+1
return ans;
}
基础不牢固,这个写了好久,还忘记了边界。
最终答案粗心把第三项和第四项的乘数敲反了居然过了那么多样例,也是惊了,以后比赛写题一定要两个人一起写!长一点的式子一定要先写在纸上!
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e9 + 10;
/*
void solve()
{
int t;
for(int i = 1; i < maxn; i++)
{
t = i % 1009 == 0 ? 1 : 0;
sum[i] = sum[i - 1] + t;
t = i % 2018 == 0 ? 1 : 0;
sum2[i] = sum2[i - 1] + t;
t = i % 2 == 0 ? 1 : 0;
even[i] = even[i - 1] + t;
}
}*/
void cal(int a, int b, ll& n2018, ll& n1009, ll& even)
{
ll left = a / 2018;
ll right = b / 2018;
ll ans = right - left;
if(a%2018==0) ans+=1; //左边是整数倍的情况 right-left会漏掉一个1
n2018 = ans;
// cout << n2018 << endl;
left = a / 1009;
right = b / 1009;
ans = right - left;
if(a%1009==0) ans+=1;
n1009 = ans;
//cout << n1009 << endl;
left = a / 2;
right = b / 2;
ans = right - left;
if(a%2==0) ans+=1;
even = ans;
// cout << even << endl;
}
LL calc(int a,int b,int x)
{
int left=a/x;
int right=b/x;
LL ans=right-left;
if(a%x==0) ans+=1;
return ans;
}
int main()
{
ll a, b, c, d;
while(scanf("%lld", &a) != EOF)
{
scanf("%lld%lld%lld", &b, &c, &d);
ll l2018, l1009, leven;
ll r2018, r1009, reven;
cal(a, b, l2018, l1009, leven);
cal(c, d, r2018, r1009, reven);
ll ans = l2018 * (d - c + 1) + (l1009 - l2018) * reven + (leven - l2018) * r1009 + (b - a + 1 - leven - l1009 + l2018) * r2018;
printf("%lld\n", ans);
}
return 0;
}