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

来源:互联网 发布:阿里云短信接口 编辑:程序博客网 时间:2024/06/07 02:44

题目链接:传送门


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 632016 20161000000000 1000000000

Sample Output

1305767523146895502644

解题思路:对于任意两个数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;}










0 0
原创粉丝点击