您的位置:首页 > 理论基础

2016年湖南省第十二届大学生计算机程序设计竞赛:A—2016

2017-05-10 23:22 513 查看


题目链接:传送门


Description

 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) 的数量:

1. 1≤a≤n,1≤b≤m;

2. a×b 是 2016 的倍数。


Input

输入包含不超过 30 组数据。

每组数据包含两个整数 n,m (1≤n,m≤109).


Output

对于每组数据,输出一个整数表示满足条件的数量。


Sample Input

32 63
2016 2016
1000000000 1000000000



Sample Output

1
30576
7523146895502644


解题思路:对于任意两个数m1=a1*2016+b1,m2=a2*2016+b2,m1*m2能否被2016整除,只要看b1*b2能否被2016整除,所以m范围内的所有数都可看成对2016取模后余数的的集合。对于n,m两个数:令k1=n/2016,k2=m/2016,r1=n%2016,r2=m%2016。
假如t1为(2016,2016)的个数,t2为(n%2016,2016)的个数,t3为(m%2016,2016)的个数。所以sum=k1*k2*t1+r1*k2*t2+r2*k1*t3+r1*r2。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
const int N = 100010;
const int M = 20;
const int INF = 99999999;

int main()
{
ull num = 0;
for( int i = 1 ; i <= 2016 ; ++i ){
for( int j = 1 ; j <= 2016 ; ++j )
if( (i*j)%2016 == 0 ) ++num;
}
ull n,m,k1,k2,r1,r2,t1,t2,t3;
while( ~scanf("%lld%lld",&n,&m) ){
ull ans = 0;
t1 = t2 = t3 = 0;
k1 = n/2016;
k2 = m/2016;
r1 = n%2016;
r2 = m%2016;
for( int i = 1 ; i <= r1 ; ++i ){
for( int j = 1 ; j <= r2 ; ++j ){
if( (i*j)%2016 == 0 ) ++t1;
}
}
for( int i = 1 ; i <= r1 ; ++i ){
for( int j = 1 ; j <= 2016 ; ++j ){
if( (i*j)%2016 == 0 ) ++t2;
}
}
for( int i = 1 ; i <= r2 ; ++i ){
for( int j = 1 ; j <= 2016 ; ++j ){
if( (i*j)%2016 == 0 ) ++t3;
}
}
ans += num*k1*k2+t1+t2*k2+t3*k1;
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学题
相关文章推荐