【数学】【NOIP普及组T2】2018

题目描述

【数学】【NOIP普及组T2】2018_第1张图片
输入
在这里插入图片描述
输出
在这里插入图片描述
样例输入
【数学】【NOIP普及组T2】2018_第2张图片
样例输出
【数学】【NOIP普及组T2】2018_第3张图片

数据范围限制

在这里插入图片描述


思路

考试的时候,看出了这是一道数学题,但是我还是没算出来 谁让我数学不好

让我们来算两张表
第一个区间:

总数 2的倍数 1009的倍数 2018的倍数
s 1 = b − a + 1 s1=b-a+1 s1=ba+1 x 1 = b / 2 − ( a − 1 ) / 2 x1=b/2-(a-1)/2 x1=b/2(a1)/2 y 1 = b / 1009 − ( a − 1 ) / 1009 y1=b/1009-(a-1)/1009 y1=b/1009(a1)/1009 z 1 = b / 2018 − ( a − 1 ) / 2018 z1=b/2018-(a-1)/2018 z1=b/2018(a1)/2018

第二个区间:

总数 2的倍数 1009的倍数 2018的倍数
s 2 = d − c + 1 s2=d-c+1 s2=dc+1 x 2 = d / 2 − ( c − 1 ) / 2 x2=d/2-(c-1)/2 x2=d/2(c1)/2 y 2 = d / 1009 − ( c − 1 ) / 1009 y2=d/1009-(c-1)/1009 y2=d/1009(c1)/1009 z 2 = d / 2018 − ( c − 1 ) / 2018 z2=d/2018-(c-1)/2018 z2=d/2018(c1)/2018
  • 2的倍数和1009的倍数相乘,求出来的都是2018的倍数。所以 a n s = x 1 ∗ y 2 + x 2 ∗ y 1 ans=x1*y2+x2*y1 ans=x1y2+x2y1
  • 让我们一起容斥。。。只要两个区间中选了一个2018的倍数,那另一个就可以随便选了,所以 z 1 ∗ s 2 z1*s2 z1s2。但是 2018 2018 2018既是 2 2 2的倍数也是 1009 1009 1009的倍数,所以在上一点已经算过了,那么就是 z 1 ∗ ( s 2 − x 2 − y 2 ) z1*(s2-x2-y2) z1(s2x2y2)。但是 (怎么这么多但是) 2 2 2 1009 1009 1009都是 2018 2018 2018的因数,所以就多减了一个 z 2 z2 z2,那么就是 z 1 ∗ ( s 2 − x 2 − y 2 + z 2 ) z1*(s2-x2-y2+z2) z1(s2x2y2+z2)
  • 和上一点同理,那么就是 z 2 ∗ ( s 1 − x 1 − y 1 + z 1 ) z2*(s1-x1-y1+z1) z2(s1x1y1+z1)。但是,我们已经 z 1 ∗ z 2 z1*z2 z1z2了,所以 z 2 z2 z2就不用在乘 z 1 z1 z1了,那么就是 z 2 ∗ ( s 1 − x 1 − y 1 ) z2*(s1-x1-y1) z2(s1x1y1)

应该简单易懂吧。。。(反正我没看懂)


#include<iostream>
#include<cstdio>
using namespace std;
long long x1,y1,z1,x2,y2,z2,n,m;
long long a,b,c,d,Gun;
int main(){
	//freopen("2018.in","r",stdin);
	//freopen("2018.out","w",stdout);
	scanf("%d%d%d%d",&a,&b,&c,&d);
	x1=b/2-(a-1)/2;
	x2=d/2-(c-1)/2;
	y1=b/1009-(a-1)/1009;
	y2=d/1009-(c-1)/1009;
	z1=b/2018-(a-1)/2018;
	z2=d/2018-(c-1)/2018;//我的表格
	Gun=x1*y2+x2*y1+z2*(b-a+1-x1-y1+z1)+z1*(d-c+1-x2-y2);//把三点和在一起
	printf("%lld",Gun);
}

你可能感兴趣的:(数学)