[CSU 1803 2016]数学
题目链接:[CSU 1803 2016]
题意描述:略。
解题思路:可以求出在
[1,N]
中,模为
[0,2016]
的数的个数; 以及在
[1,M]
中,模为
[0,2016]
的数的个数。复杂度
O(2016)
因为
x∗y%2016=x%2016∗y%2016
,那么,接下来就只需要统计求和就OK了。
这个题目的容斥,我一直还没有搞清…
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef long long LL;
typedef pair<int, int> PII;
const int MAXN = 2016 + 5;
const int INF = 0x3f3f3f3f;
LL N, M;
LL cnta[MAXN], cntb[MAXN];
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
LL x, y, ans;
while(~scanf("%lld %lld", &N, &M)) {
memset(cnta, 0, sizeof(cnta));
memset(cntb, 0, sizeof(cntb));
x = N / 2016, y = N % 2016;
for (LL i = 0; i < 2016; i++) {
if(i != 0 && i <= y) cnta[i] = x + 1;
else cnta[i] = x;
}
x = M / 2016, y = M % 2016;
for (LL i = 0; i < 2016; i++) {
if(i != 0 && i <= y) cntb[i] = x + 1;
else cntb[i] = x;
}
ans = 0;
for (LL i = 0; i < 2016; i++) {
if(cnta[i] == 0) continue;
for (LL j = 0; j < 2016; j++) {
if(cntb[j] == 0) continue;
if(i * j % 2016 == 0) {
ans += cnta[i] * cntb[j];
}
}
}
printf("%lld\n", ans);
}
return 0;
}