我需要帮助找出解决这个问题的更好方法(也许更多数学问题!)。以下是详细信息:
问题陈述:
给定N和M,你需要找出有多少对a,b(1 <= a
约束:1&lt; = N&lt; = 10 ^ 9且2 <= M <= 10 ^ 9. 时间限制:1秒
在我的算法中,我已经循环N次,使其成为O(N)算法。这是代码:
#include <stdio.h>
typedef unsigned long long ULL;
int main()
{
int t,m,n,a; ULL ans=0;
scanf("%d\n",&t);
while(t--) // test cases
{
// Main logic
scanf("%d %d",&n,&m);
ans=0;
for(a=1;a<n;a++)
ans += (n+a)/m - (a*2)/m;
printf("%llu\n",ans);
}
return 0;
}
我只是检查在范围(2a,n + a)中可以被M整除的数量,其中1 =&lt; a&lt; ñ。如果您查看范围内所有(a,b)的总和,您就会知道我为什么选择(2a,n + a)。
然而,这种 O(N)方法并不是很快。对于N = 10 9 且M = 2,程序在12秒内打印答案为249999999500000000,这非常慢。还可以使用哪些其他方法?我想不出更好的方法。请帮忙!
答案 0 :(得分:3)
而不是测试,你可以简单地计算。
让我们列出所有可能的对:
(1, N - (N+1)%M),
(1, N - M - (N+1)%M),
(1, N - 2*M - (N+1)%M),
...
(2, N - (N+1)%M - 1),
(2, N - M - (N+1)%M - 1),
(2, N - 2*M - (N+1)%M - 1),
...
(我们需要从元组的第二个元素中减去(N+1)%M
,以使元素总和被M除尽。
更一般地说,给定N
和M
&gt; 0,每对(a, b)
与1 <= a < b <= N
,a+b % M == 0
必须具有以下形式:
(i+1, N - d*M - (N+1)%M - i)
和0 <= d
的 0 <= i
现在你必须回答以下两个问题:
i
的最大值是什么?i
,d
的最大值是多少,即对于每个有效的i
,有多少对(i+1, ...)
确实存在?一旦你发现了,你应该能够提出一个公式来确定恒定时间内有效对的数量。
答案 1 :(得分:0)
ans = n / m * (n - 1)
+ (n / m) * (n / m - 1) / 2 * m
+ (n % m + m / 2) / m * (n - m + n % m)
+ (n - m + n % m) % m * (n / m)
- (n / m) * (n / m - 1) * m
- (m / 2) * (n / m)
- (n % m) * (n / m * 2)
- (n % m / ((m + 1) / 2)) * (n % m % ((m + 1) / 2));