首页 > 其他 > 详细

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

时间:2020-04-11 14:27:21      阅读:75      评论:0      收藏:0      [点我收藏+]

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

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

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

\[\therefore (a+b)(b-a+1)\bmod 2=0 \]

\[\because \text{两数和、差的奇偶性相同} \]

\[\therefore (a+b)\text{ 和 }(b-a)\text{ 的奇偶性相同} \]

\[\therefore (a+b)\text{ 和 }(b-a+1)\text{ 的奇偶性不同} \]

由此,我们只需要枚举 \((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;
}

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

原文:https://www.cnblogs.com/Xray-luogu/p/12679256.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!