[SHOI2002]N的连续数拆分 题解

一道比较简单的数学题。
题目问我们正整数 (n) 可以被多少组连续的正整数拆分。那么这些连续的正整数会组成一个公差为 (1) 的等差数列。
设数列的首项为 (a),末项为 (b),则该等差数列的和为 (dfrac{(a+b)(b-a+1)}{2})
然后来推一波柿子:

[ecause dfrac{(a+b)(b-a+1)}{2}=n ]

[ herefore (a+b)(b-a+1)=2n ]

[ herefore (a+b)(b-a+1)mod 2=0 ]

[ecause ext{两数和、差的奇偶性相同} ]

[ herefore (a+b) ext{ 和 }(b-a) ext{ 的奇偶性相同} ]

[ herefore (a+b) ext{ 和 }(b-a+1) ext{ 的奇偶性不同} ]

由此,我们只需要枚举 ((a+b)),判断其是否为 (2n) 的因子。若是,则求出 ((b-a+1))。如果 ((a+b))((b-a+1)) 的奇偶性不同,则方案数增加。
时间复杂度为 (O(sqrt{n})),常数为 (sqrt{2})
(11) 行代码(未压行):

#include <bits/stdc++.h>
using namespace std;
long long n;
int main() {
	scanf("%lld",&n);
	n<<=1; // 之后不需要使用 n 了,只需要用 2n,故直接将 n 乘上 2
	int ans=0,m=sqrt(n);
	for (register int i=1,j;i<=m;i++) ans+=!(n%i)&&(i&1)^(n/i&1); // 位运算。等价于 if (n%i==0&&i%2!=n/i%2) ans++;
	printf("%d",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Xray-luogu/p/12679256.html