题目:http://acm.hdu.edu.cn/showproblem.php?pid=2601
AC代码(C++):
#include <iostream> #include <queue> #include <string> #include <algorithm> #include <math.h> #define INF 0x3f3f3f3f #define eps 1e-8 using namespace std; long long A; int main() { int t; cin >> t; while (t--) { cin >> A; A++; long long ans = 1; for (long long i = 2; i*i <= A;) { if (A%i == 0) { long long k = 0; while (A%i == 0) { k++; A /= i; } ans *= k + 1; } if (i == 2)i++; else i += 2; } if (A != 1) { ans *= 2; } ans = (ans + 1) / 2 - 1; cout << ans << endl; } //system("pause"); }总结: 数学题. 思路是先把n=i*j+i+j化成n+1=(i+1)(j+1), 然后用整数的唯一分解法(即对任意整数有A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pm^km), 其中pi均为素数)分解n+1, 求出约数的个数(k1+1)*(k2+1)*...*(km+1), 然后两两组合就行了. 有几点需要特别小心...WA了好几次. 一是要用longlong来装数, 否则溢出. 二是要注意, 如果存在i=j使得等式成立, 那么答案就不是约数个数除以2减1(减1是因为约数里包括1和n+1自身)这么简单了, 因为约数里n+1的开方只出现了一次, 所以在除以2减1之前再加1就行了. 考虑到整数截断的特性, 可以不管什么情况都先加1.